Extracts carrier information from QSFooterImpl

QSCarrierGroup performs the same logic and visuals that were inside
QSFooterImpl

Extracted to QSCarrier

Supports up to 3 sims

Test: atest QSFooterImpl
Test: atest QSCarrierGroup
Test: manual
Change-Id: I44e6f917e176af7f305a1de235e1a5be52da579c
diff --git a/packages/SystemUI/res/layout/qs_footer_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
similarity index 90%
rename from packages/SystemUI/res/layout/qs_footer_carrier.xml
rename to packages/SystemUI/res/layout/qs_carrier.xml
index bd492b0..089a7e7 100644
--- a/packages/SystemUI/res/layout/qs_footer_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -14,9 +14,9 @@
   ~ limitations under the License
   -->
 
-<LinearLayout
+<com.android.systemui.qs.QSCarrier
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/linear_footer_carrier"
+    android:id="@+id/linear_carrier"
     android:layout_width="0dp"
     android:layout_height="match_parent"
     android:orientation="horizontal"
@@ -35,7 +35,7 @@
         android:layout_marginEnd="8dp"
         android:visibility="gone" />
 
-    <view class="com.android.systemui.qs.QSFooterImpl$QSCarrierText"
+    <view class="com.android.systemui.qs.QSCarrier$QSCarrierText"
         android:id="@+id/qs_carrier_text"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
@@ -46,4 +46,4 @@
         android:textDirection="locale"
         android:singleLine="true" />
 
-</LinearLayout>
\ No newline at end of file
+</com.android.systemui.qs.QSCarrier>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml
new file mode 100644
index 0000000..1303562
--- /dev/null
+++ b/packages/SystemUI/res/layout/qs_carrier_group.xml
@@ -0,0 +1,60 @@
+<!--
+  Copyright (C) 2019 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License
+  -->
+
+<!-- Extends LinearLayout -->
+<com.android.systemui.qs.QSCarrierGroup
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/qs_mobile"
+    android:layout_width="0dp"
+    android:layout_height="match_parent"
+    android:layout_weight="1"
+    android:gravity="center_vertical|start"
+    android:orientation="horizontal"
+    android:layout_marginEnd="32dp">
+
+    <include
+        layout="@layout/qs_carrier"
+        android:id="@+id/carrier1" />
+
+    <View
+        android:id="@+id/qs_carrier_divider1"
+        android:layout_width="2dp"
+        android:layout_height="match_parent"
+        android:layout_marginTop="15dp"
+        android:layout_marginBottom="15dp"
+        android:background="?android:attr/dividerVertical"
+        android:visibility="gone" />
+
+    <include
+        layout="@layout/qs_carrier"
+        android:id="@+id/carrier2"
+        android:visibility="gone"/>
+
+    <View
+        android:id="@+id/qs_carrier_divider2"
+        android:layout_width="2dp"
+        android:layout_height="match_parent"
+        android:layout_marginTop="15dp"
+        android:layout_marginBottom="15dp"
+        android:background="?android:attr/dividerVertical"
+        android:visibility="gone" />
+
+    <include
+        layout="@layout/qs_carrier"
+        android:id="@+id/carrier3"
+        android:visibility="gone"/>
+
+</com.android.systemui.qs.QSCarrierGroup>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 67e31ac..fb2a343 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -41,34 +41,8 @@
         android:layout_gravity="center_vertical"
         android:gravity="end" >
 
-        <LinearLayout
-            android:id="@+id/qs_mobile"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:gravity="center_vertical|start"
-            android:orientation="horizontal"
-            android:layout_marginEnd="32dp">
-
-            <include
-                layout="@layout/qs_footer_carrier"
-                android:id="@+id/carrier1" />
-
-            <View
-                android:id="@+id/qs_carrier_divider"
-                android:layout_width="2dp"
-                android:layout_height="match_parent"
-                android:layout_marginTop="15dp"
-                android:layout_marginBottom="15dp"
-                android:background="?android:attr/dividerVertical"
-                android:visibility="gone" />
-
-            <include
-                layout="@layout/qs_footer_carrier"
-                android:id="@+id/carrier2"
-                android:visibility="gone"/>
-
-        </LinearLayout>
+        <include layout="@layout/qs_carrier_group"
+        android:id="@+id/carrier_group"/>
 
         <com.android.systemui.qs.PageIndicator
             android:id="@+id/footer_page_indicator"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
new file mode 100644
index 0000000..ec842f1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import com.android.settingslib.Utils;
+import com.android.settingslib.graph.SignalDrawable;
+import com.android.systemui.R;
+
+public class QSCarrier extends LinearLayout {
+
+    private View mMobileGroup;
+    private TextView mCarrierText;
+    private ImageView mMobileSignal;
+    private ImageView mMobileRoaming;
+    private ColorStateList mColorForegroundStateList;
+    private float mColorForegroundIntensity;
+
+    public QSCarrier(Context context) {
+        super(context);
+    }
+
+    public QSCarrier(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mMobileGroup = findViewById(R.id.mobile_combo);
+        mMobileSignal = findViewById(R.id.mobile_signal);
+        mMobileRoaming = findViewById(R.id.mobile_roaming);
+        mCarrierText = findViewById(R.id.qs_carrier_text);
+
+        int colorForeground = Utils.getColorAttrDefaultColor(mContext,
+                android.R.attr.colorForeground);
+        mColorForegroundStateList = ColorStateList.valueOf(colorForeground);
+        mColorForegroundIntensity = QuickStatusBarHeader.getColorIntensity(colorForeground);
+
+    }
+
+    public void updateState(QSCarrierGroup.CellSignalState state) {
+        mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE);
+        if (state.visible) {
+            mMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE);
+            mMobileRoaming.setImageTintList(mColorForegroundStateList);
+            SignalDrawable d = new SignalDrawable(mContext);
+            d.setDarkIntensity(mColorForegroundIntensity);
+            mMobileSignal.setImageDrawable(d);
+            mMobileSignal.setImageLevel(state.mobileSignalIconId);
+
+            StringBuilder contentDescription = new StringBuilder();
+            if (state.contentDescription != null) {
+                contentDescription.append(state.contentDescription).append(", ");
+            }
+            if (state.roaming) {
+                contentDescription
+                        .append(mContext.getString(R.string.data_connection_roaming))
+                        .append(", ");
+            }
+            // TODO: show mobile data off/no internet text for 5 seconds before carrier text
+            if (TextUtils.equals(state.typeContentDescription,
+                    mContext.getString(R.string.data_connection_no_internet))
+                    || TextUtils.equals(state.typeContentDescription,
+                    mContext.getString(R.string.cell_data_off_content_description))) {
+                contentDescription.append(state.typeContentDescription);
+            }
+            mMobileSignal.setContentDescription(contentDescription);
+        }
+    }
+
+    public void setCarrierText(CharSequence text) {
+        mCarrierText.setText(text);
+    }
+
+    /**
+     * TextView that changes its ellipsize value with its visibility.
+     */
+    public static class QSCarrierText extends TextView {
+        public QSCarrierText(Context context) {
+            super(context);
+        }
+
+        public QSCarrierText(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr) {
+            super(context, attrs, defStyleAttr);
+        }
+
+        public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+        }
+
+        @Override
+        protected void onVisibilityChanged(View changedView, int visibility) {
+            super.onVisibilityChanged(changedView, visibility);
+            // Only show marquee when visible
+            if (visibility == VISIBLE) {
+                setEllipsize(TextUtils.TruncateAt.MARQUEE);
+                setSelected(true);
+            } else {
+                setEllipsize(TextUtils.TruncateAt.END);
+                setSelected(false);
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
new file mode 100644
index 0000000..9b625ac
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+
+import android.content.Context;
+import android.telephony.SubscriptionManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.keyguard.CarrierTextController;
+import com.android.systemui.Dependency;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * Displays Carrier name and network status in QS
+ */
+public class QSCarrierGroup extends LinearLayout implements
+        CarrierTextController.CarrierTextCallback,
+        NetworkController.SignalCallback {
+
+    private static final String TAG = "QSCarrierGroup";
+    /**
+     * Support up to 3 slots which is what's supported by {@link TelephonyManager#getPhoneCount}
+     */
+    private static final int SIM_SLOTS = 3;
+    private final NetworkController mNetworkController;
+
+    private View[] mCarrierDividers = new View[SIM_SLOTS - 1];
+    private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS];
+    private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS];
+    private CarrierTextController mCarrierTextController;
+
+    private boolean mListening;
+
+    @Inject
+    public QSCarrierGroup(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+            NetworkController networkController) {
+        super(context, attrs);
+        mNetworkController = networkController;
+    }
+
+    @VisibleForTesting
+    public QSCarrierGroup(Context context, AttributeSet attrs) {
+        this(context, attrs,
+                Dependency.get(NetworkController.class));
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mCarrierGroups[0] = findViewById(R.id.carrier1);
+        mCarrierGroups[1] = findViewById(R.id.carrier2);
+        mCarrierGroups[2] = findViewById(R.id.carrier3);
+
+        mCarrierDividers[0] = findViewById(R.id.qs_carrier_divider1);
+        mCarrierDividers[1] = findViewById(R.id.qs_carrier_divider2);
+
+        for (int i = 0; i < SIM_SLOTS; i++) {
+            mInfos[i] = new CellSignalState();
+        }
+
+        CharSequence separator = mContext.getString(
+                com.android.internal.R.string.kg_text_message_separator);
+        mCarrierTextController = new CarrierTextController(mContext, separator, false, false);
+        setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
+    }
+
+    public void setListening(boolean listening) {
+        if (listening == mListening) {
+            return;
+        }
+        mListening = listening;
+        updateListeners();
+    }
+
+    @Override
+    @VisibleForTesting
+    public void onDetachedFromWindow() {
+        setListening(false);
+        super.onDetachedFromWindow();
+    }
+
+    private void updateListeners() {
+        if (mListening) {
+            if (mNetworkController.hasVoiceCallingFeature()) {
+                mNetworkController.addCallback(this);
+            }
+            mCarrierTextController.setListening(this);
+        } else {
+            mNetworkController.removeCallback(this);
+            mCarrierTextController.setListening(null);
+        }
+    }
+
+    private void handleUpdateState() {
+        for (int i = 0; i < SIM_SLOTS; i++) {
+            mCarrierGroups[i].updateState(mInfos[i]);
+        }
+        mCarrierDividers[0].setVisibility(
+                mInfos[0].visible && mInfos[1].visible ? View.VISIBLE : View.GONE);
+        // This tackles the case of slots 2 being available as well as at least one other.
+        // In that case we show the second divider. Note that if both dividers are visible, it means
+        // all three slots are in use, and that is correct.
+        mCarrierDividers[1].setVisibility(
+                (mInfos[1].visible && mInfos[2].visible)
+                        || (mInfos[0].visible && mInfos[2].visible) ? View.VISIBLE : View.GONE);
+    }
+
+    @VisibleForTesting
+    protected int getSlotIndex(int subscriptionId) {
+        return SubscriptionManager.getSlotIndex(subscriptionId);
+    }
+
+    @Override
+    public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
+        if (info.anySimReady) {
+            boolean[] slotSeen = new boolean[SIM_SLOTS];
+            if (info.listOfCarriers.length == info.subscriptionIds.length) {
+                for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
+                    int slot = getSlotIndex(info.subscriptionIds[i]);
+                    if (slot >= SIM_SLOTS) {
+                        Log.w(TAG, "updateInfoCarrier - slot: " + slot);
+                        continue;
+                    }
+                    if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+                        Log.e(TAG,
+                                "Invalid SIM slot index for subscription: "
+                                        + info.subscriptionIds[i]);
+                        continue;
+                    }
+                    mInfos[slot].visible = true;
+                    slotSeen[slot] = true;
+                    mCarrierGroups[slot].setCarrierText(info.listOfCarriers[i].toString().trim());
+                    mCarrierGroups[slot].setVisibility(View.VISIBLE);
+                }
+                for (int i = 0; i < SIM_SLOTS; i++) {
+                    if (!slotSeen[i]) {
+                        mInfos[i].visible = false;
+                        mCarrierGroups[i].setVisibility(View.GONE);
+                    }
+                }
+            } else {
+                Log.e(TAG, "Carrier information arrays not of same length");
+            }
+        } else {
+            mInfos[0].visible = false;
+            mCarrierGroups[0].setCarrierText(info.carrierText);
+            mCarrierGroups[0].setVisibility(View.VISIBLE);
+            for (int i = 1; i < SIM_SLOTS; i++) {
+                mInfos[i].visible = false;
+                mCarrierGroups[i].setCarrierText("");
+                mCarrierGroups[i].setVisibility(View.GONE);
+            }
+        }
+        handleUpdateState();
+    }
+
+    @Override
+    public void setMobileDataIndicators(NetworkController.IconState statusIcon,
+            NetworkController.IconState qsIcon, int statusType,
+            int qsType, boolean activityIn, boolean activityOut,
+            String typeContentDescription,
+            String description, boolean isWide, int subId, boolean roaming) {
+        int slotIndex = getSlotIndex(subId);
+        if (slotIndex >= SIM_SLOTS) {
+            Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
+            return;
+        }
+        if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+            Log.e(TAG, "Invalid SIM slot index for subscription: " + subId);
+            return;
+        }
+        mInfos[slotIndex].visible = statusIcon.visible;
+        mInfos[slotIndex].mobileSignalIconId = statusIcon.icon;
+        mInfos[slotIndex].contentDescription = statusIcon.contentDescription;
+        mInfos[slotIndex].typeContentDescription = typeContentDescription;
+        mInfos[slotIndex].roaming = roaming;
+        handleUpdateState();
+    }
+
+    @Override
+    public void setNoSims(boolean hasNoSims, boolean simDetected) {
+        if (hasNoSims) {
+            for (int i = 0; i < SIM_SLOTS; i++) {
+                mInfos[i].visible = false;
+            }
+        }
+        handleUpdateState();
+    }
+
+    static final class CellSignalState {
+        boolean visible;
+        int mobileSignalIconId;
+        String contentDescription;
+        String typeContentDescription;
+        boolean roaming;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index bbd8de3..dcb33e4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -23,25 +23,19 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.UserInfo;
-import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.RippleDrawable;
 import android.os.Bundle;
 import android.os.UserManager;
-import android.telephony.SubscriptionManager;
-import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
-import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
-import android.widget.TextView;
 import android.widget.Toast;
 
 import androidx.annotation.Nullable;
@@ -49,11 +43,9 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.keyguard.CarrierTextController;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.settingslib.Utils;
 import com.android.settingslib.drawable.UserIconDrawable;
-import com.android.settingslib.graph.SignalDrawable;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.R.dimen;
@@ -62,9 +54,6 @@
 import com.android.systemui.statusbar.phone.MultiUserSwitch;
 import com.android.systemui.statusbar.phone.SettingsButton;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.NetworkController;
-import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener;
-import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
 import com.android.systemui.statusbar.policy.UserInfoController;
 import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
 import com.android.systemui.tuner.TunerService;
@@ -73,15 +62,12 @@
 import javax.inject.Named;
 
 public class QSFooterImpl extends FrameLayout implements QSFooter,
-        OnClickListener, OnUserInfoChangedListener, EmergencyListener, SignalCallback,
-        CarrierTextController.CarrierTextCallback {
+        OnClickListener, OnUserInfoChangedListener {
 
-    private static final int SIM_SLOTS = 2;
     private static final String TAG = "QSFooterImpl";
 
     private final ActivityStarter mActivityStarter;
     private final UserInfoController mUserInfoController;
-    private final NetworkController mNetworkController;
     private final DeviceProvisionedController mDeviceProvisionedController;
     private SettingsButton mSettingsButton;
     protected View mSettingsContainer;
@@ -94,7 +80,7 @@
 
     private boolean mListening;
 
-    private boolean mShowEmergencyCallsOnly;
+    private QSCarrierGroup mCarrierGroup;
     private View mDivider;
     protected MultiUserSwitch mMultiUserSwitch;
     private ImageView mMultiUserAvatar;
@@ -108,30 +94,15 @@
     private View mActionsContainer;
     private View mDragHandle;
 
-    private View mCarrierDivider;
-    private ViewGroup mMobileFooter;
-    private View[] mMobileGroups = new View[SIM_SLOTS];
-    private ViewGroup[] mCarrierGroups = new ViewGroup[SIM_SLOTS];
-    private TextView[] mCarrierTexts = new TextView[SIM_SLOTS];
-    private ImageView[] mMobileSignals = new ImageView[SIM_SLOTS];
-    private ImageView[] mMobileRoamings = new ImageView[SIM_SLOTS];
-    private final CellSignalState[] mInfos =
-            new CellSignalState[]{new CellSignalState(), new CellSignalState()};
-
-    private final int mColorForeground;
     private OnClickListener mExpandClickListener;
-    private CarrierTextController mCarrierTextController;
 
     @Inject
     public QSFooterImpl(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
             ActivityStarter activityStarter, UserInfoController userInfoController,
-            NetworkController networkController,
             DeviceProvisionedController deviceProvisionedController) {
         super(context, attrs);
-        mColorForeground = Utils.getColorAttrDefaultColor(context, android.R.attr.colorForeground);
         mActivityStarter = activityStarter;
         mUserInfoController = userInfoController;
-        mNetworkController = networkController;
         mDeviceProvisionedController = deviceProvisionedController;
     }
 
@@ -140,7 +111,6 @@
         this(context, attrs,
                 Dependency.get(ActivityStarter.class),
                 Dependency.get(UserInfoController.class),
-                Dependency.get(NetworkController.class),
                 Dependency.get(DeviceProvisionedController.class));
     }
 
@@ -159,20 +129,7 @@
         mSettingsContainer = findViewById(R.id.settings_button_container);
         mSettingsButton.setOnClickListener(this);
 
-        mMobileFooter = findViewById(R.id.qs_mobile);
-        mCarrierGroups[0] = findViewById(R.id.carrier1);
-        mCarrierGroups[1] = findViewById(R.id.carrier2);
-
-        for (int i = 0; i < SIM_SLOTS; i++) {
-            mMobileGroups[i] = mCarrierGroups[i].findViewById(R.id.mobile_combo);
-            mMobileSignals[i] = mCarrierGroups[i].findViewById(R.id.mobile_signal);
-            mMobileRoamings[i] = mCarrierGroups[i].findViewById(R.id.mobile_roaming);
-            mCarrierTexts[i] = mCarrierGroups[i].findViewById(R.id.qs_carrier_text);
-        }
-        mCarrierDivider = findViewById(R.id.qs_carrier_divider);
-        CharSequence separator = mContext.getString(
-                com.android.internal.R.string.kg_text_message_separator);
-        mCarrierTextController = new CarrierTextController(mContext, separator, false, false);
+        mCarrierGroup = findViewById(R.id.carrier_group);
 
         mMultiUserSwitch = findViewById(R.id.multi_user_switch);
         mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
@@ -240,8 +197,7 @@
     private TouchAnimator createFooterAnimator() {
         return new TouchAnimator.Builder()
                 .addFloat(mDivider, "alpha", 0, 1)
-                .addFloat(mMobileFooter, "alpha", 0, 0, 1)
-                .addFloat(mCarrierDivider, "alpha", 0, 1)
+                .addFloat(mCarrierGroup, "alpha", 0, 0, 1)
                 .addFloat(mActionsContainer, "alpha", 0, 1)
                 .addFloat(mDragHandle, "alpha", 1, 0, 0)
                 .addFloat(mPageIndicator, "alpha", 0, 1)
@@ -364,17 +320,10 @@
     private void updateListeners() {
         if (mListening) {
             mUserInfoController.addCallback(this);
-            if (mNetworkController.hasVoiceCallingFeature()) {
-                mNetworkController.addEmergencyListener(this);
-                mNetworkController.addCallback(this);
-            }
-            mCarrierTextController.setListening(this);
         } else {
             mUserInfoController.removeCallback(this);
-            mNetworkController.removeEmergencyListener(this);
-            mNetworkController.removeCallback(this);
-            mCarrierTextController.setListening(null);
         }
+        mCarrierGroup.setListening(mListening);
     }
 
     @Override
@@ -430,17 +379,6 @@
     }
 
     @Override
-    public void setEmergencyCallsOnly(boolean show) {
-        boolean changed = show != mShowEmergencyCallsOnly;
-        if (changed) {
-            mShowEmergencyCallsOnly = show;
-            if (mExpanded) {
-                updateEverything();
-            }
-        }
-    }
-
-    @Override
     public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
         if (picture != null &&
                 UserManager.get(mContext).isGuestUser(KeyguardUpdateMonitor.getCurrentUser()) &&
@@ -452,162 +390,4 @@
         }
         mMultiUserAvatar.setImageDrawable(picture);
     }
-
-    private void handleUpdateState() {
-        for (int i = 0; i < SIM_SLOTS; i++) {
-            mMobileGroups[i].setVisibility(mInfos[i].visible ? View.VISIBLE : View.GONE);
-            if (mInfos[i].visible) {
-                mMobileRoamings[i].setVisibility(mInfos[i].roaming ? View.VISIBLE : View.GONE);
-                mMobileRoamings[i].setImageTintList(ColorStateList.valueOf(mColorForeground));
-                SignalDrawable d = new SignalDrawable(mContext);
-                d.setDarkIntensity(QuickStatusBarHeader.getColorIntensity(mColorForeground));
-                mMobileSignals[i].setImageDrawable(d);
-                mMobileSignals[i].setImageLevel(mInfos[i].mobileSignalIconId);
-
-                StringBuilder contentDescription = new StringBuilder();
-                if (mInfos[i].contentDescription != null) {
-                    contentDescription.append(mInfos[i].contentDescription).append(", ");
-                }
-                if (mInfos[i].roaming) {
-                    contentDescription
-                            .append(mContext.getString(R.string.data_connection_roaming))
-                            .append(", ");
-                }
-                // TODO: show mobile data off/no internet text for 5 seconds before carrier text
-                if (TextUtils.equals(mInfos[i].typeContentDescription,
-                        mContext.getString(R.string.data_connection_no_internet))
-                        || TextUtils.equals(mInfos[i].typeContentDescription,
-                        mContext.getString(R.string.cell_data_off_content_description))) {
-                    contentDescription.append(mInfos[i].typeContentDescription);
-                }
-                mMobileSignals[i].setContentDescription(contentDescription);
-            }
-        }
-        mCarrierDivider.setVisibility(
-                mInfos[0].visible && mInfos[1].visible ? View.VISIBLE : View.GONE);
-    }
-
-    @VisibleForTesting
-    protected int getSlotIndex(int subscriptionId) {
-        return SubscriptionManager.getSlotIndex(subscriptionId);
-    }
-
-    @Override
-    public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
-        if (info.anySimReady) {
-            boolean[] slotSeen = new boolean[SIM_SLOTS];
-            if (info.listOfCarriers.length == info.subscriptionIds.length) {
-                for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) {
-                    int slot = getSlotIndex(info.subscriptionIds[i]);
-                    if (slot >= SIM_SLOTS) {
-                        Log.w(TAG, "updateInfoCarrier - slot: " + slot);
-                        continue;
-                    }
-                    if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                        Log.e(TAG,
-                                "Invalid SIM slot index for subscription: "
-                                        + info.subscriptionIds[i]);
-                        continue;
-                    }
-                    mInfos[slot].visible = true;
-                    slotSeen[slot] = true;
-                    mCarrierTexts[slot].setText(info.listOfCarriers[i].toString().trim());
-                    mCarrierGroups[slot].setVisibility(View.VISIBLE);
-                }
-                for (int i = 0; i < SIM_SLOTS; i++) {
-                    if (!slotSeen[i]) {
-                        mInfos[i].visible = false;
-                        mCarrierGroups[i].setVisibility(View.GONE);
-                    }
-                }
-            } else {
-                Log.e(TAG, "Carrier information arrays not of same length");
-            }
-        } else {
-            mInfos[0].visible = false;
-            mCarrierTexts[0].setText(info.carrierText);
-            mCarrierGroups[0].setVisibility(View.VISIBLE);
-            for (int i = 1; i < SIM_SLOTS; i++) {
-                mInfos[i].visible = false;
-                mCarrierTexts[i].setText("");
-                mCarrierGroups[i].setVisibility(View.GONE);
-            }
-        }
-        handleUpdateState();
-    }
-
-    @Override
-    public void setMobileDataIndicators(NetworkController.IconState statusIcon,
-            NetworkController.IconState qsIcon, int statusType,
-            int qsType, boolean activityIn, boolean activityOut,
-            String typeContentDescription,
-            String description, boolean isWide, int subId, boolean roaming) {
-        int slotIndex = getSlotIndex(subId);
-        if (slotIndex >= SIM_SLOTS) {
-            Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex);
-            return;
-        }
-        if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-            Log.e(TAG, "Invalid SIM slot index for subscription: " + subId);
-            return;
-        }
-        mInfos[slotIndex].visible = statusIcon.visible;
-        mInfos[slotIndex].mobileSignalIconId = statusIcon.icon;
-        mInfos[slotIndex].contentDescription = statusIcon.contentDescription;
-        mInfos[slotIndex].typeContentDescription = typeContentDescription;
-        mInfos[slotIndex].roaming = roaming;
-        handleUpdateState();
-    }
-
-    @Override
-    public void setNoSims(boolean hasNoSims, boolean simDetected) {
-        if (hasNoSims) {
-            mInfos[0].visible = false;
-            mInfos[1].visible = false;
-        }
-        handleUpdateState();
-    }
-
-    private final class CellSignalState {
-        boolean visible;
-        int mobileSignalIconId;
-        public String contentDescription;
-        String typeContentDescription;
-        boolean roaming;
-    }
-
-    /**
-     * TextView that changes its ellipsize value with its visibility.
-     */
-    public static class QSCarrierText extends TextView {
-        public QSCarrierText(Context context) {
-            super(context);
-        }
-
-        public QSCarrierText(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr) {
-            super(context, attrs, defStyleAttr);
-        }
-
-        public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr,
-                int defStyleRes) {
-            super(context, attrs, defStyleAttr, defStyleRes);
-        }
-
-        @Override
-        protected void onVisibilityChanged(View changedView, int visibility) {
-            super.onVisibilityChanged(changedView, visibility);
-            // Only show marquee when visible
-            if (visibility == VISIBLE) {
-                setEllipsize(TextUtils.TruncateAt.MARQUEE);
-                setSelected(true);
-            } else {
-                setEllipsize(TextUtils.TruncateAt.END);
-                setSelected(false);
-            }
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index c6636b4..e6b6672 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -24,6 +24,7 @@
 import android.view.View;
 
 import com.android.systemui.SystemUIFactory;
+import com.android.systemui.qs.QSCarrierGroup;
 import com.android.systemui.qs.QSFooterImpl;
 import com.android.systemui.qs.QuickStatusBarHeader;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -124,6 +125,11 @@
          * Creates the NotificationPanelView.
          */
         NotificationPanelView createPanelView();
+
+        /**
+         * Creates the QSCarrierGroup
+         */
+        QSCarrierGroup createQSCarrierGroup();
     }
 
     /**
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java
new file mode 100644
index 0000000..f29392b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.qs;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.telephony.SubscriptionManager;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.LayoutInflater;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.keyguard.CarrierTextController;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.utils.leaks.LeakCheckedTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class QSCarrierGroupTest extends LeakCheckedTest {
+
+    private QSCarrierGroup mCarrierGroup;
+
+    @Before
+    public void setup() throws Exception {
+        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
+        TestableLooper.get(this).runWithLooper(
+                () -> mCarrierGroup = (QSCarrierGroup) LayoutInflater.from(mContext).inflate(
+                        R.layout.qs_carrier_group, null));
+    }
+
+    @Test // throws no Exception
+    public void testUpdateCarrierText_sameLengths() {
+        QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup);
+        when(spiedCarrierGroup.getSlotIndex(anyInt())).thenAnswer(
+                new Answer<Integer>() {
+                    @Override
+                    public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
+                        return invocationOnMock.getArgument(0);
+                    }
+                });
+
+        // listOfCarriers length 1, subscriptionIds length 1, anySims false
+        CarrierTextController.CarrierTextCallbackInfo
+                c1 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{""},
+                false,
+                new int[]{0});
+        spiedCarrierGroup.updateCarrierInfo(c1);
+
+        // listOfCarriers length 1, subscriptionIds length 1, anySims true
+        CarrierTextController.CarrierTextCallbackInfo
+                c2 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{""},
+                true,
+                new int[]{0});
+        spiedCarrierGroup.updateCarrierInfo(c2);
+
+        // listOfCarriers length 2, subscriptionIds length 2, anySims false
+        CarrierTextController.CarrierTextCallbackInfo
+                c3 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{"", ""},
+                false,
+                new int[]{0, 1});
+        spiedCarrierGroup.updateCarrierInfo(c3);
+
+        // listOfCarriers length 2, subscriptionIds length 2, anySims true
+        CarrierTextController.CarrierTextCallbackInfo
+                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{"", ""},
+                true,
+                new int[]{0, 1});
+        spiedCarrierGroup.updateCarrierInfo(c4);
+    }
+
+    @Test // throws no Exception
+    public void testUpdateCarrierText_differentLength() {
+        QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup);
+        when(spiedCarrierGroup.getSlotIndex(anyInt())).thenAnswer(
+                new Answer<Integer>() {
+                    @Override
+                    public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
+                        return invocationOnMock.getArgument(0);
+                    }
+                });
+
+        // listOfCarriers length 2, subscriptionIds length 1, anySims false
+        CarrierTextController.CarrierTextCallbackInfo
+                c1 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{"", ""},
+                false,
+                new int[]{0});
+        spiedCarrierGroup.updateCarrierInfo(c1);
+
+        // listOfCarriers length 2, subscriptionIds length 1, anySims true
+        CarrierTextController.CarrierTextCallbackInfo
+                c2 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{"", ""},
+                true,
+                new int[]{0});
+        spiedCarrierGroup.updateCarrierInfo(c2);
+
+        // listOfCarriers length 1, subscriptionIds length 2, anySims false
+        CarrierTextController.CarrierTextCallbackInfo
+                c3 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{""},
+                false,
+                new int[]{0, 1});
+        spiedCarrierGroup.updateCarrierInfo(c3);
+
+        // listOfCarriers length 1, subscriptionIds length 2, anySims true
+        CarrierTextController.CarrierTextCallbackInfo
+                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{""},
+                true,
+                new int[]{0, 1});
+        spiedCarrierGroup.updateCarrierInfo(c4);
+    }
+
+    @Test // throws no Exception
+    public void testUpdateCarrierText_invalidSim() {
+        QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup);
+        when(spiedCarrierGroup.getSlotIndex(anyInt())).thenReturn(
+                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        CarrierTextController.CarrierTextCallbackInfo
+                c4 = new CarrierTextController.CarrierTextCallbackInfo(
+                "",
+                new CharSequence[]{"", ""},
+                true,
+                new int[]{0, 1});
+        spiedCarrierGroup.updateCarrierInfo(c4);
+    }
+
+    @Test // throws no Exception
+    public void testSetMobileDataIndicators_invalidSim() {
+        QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup);
+        when(spiedCarrierGroup.getSlotIndex(anyInt())).thenReturn(
+                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        spiedCarrierGroup.setMobileDataIndicators(
+                mock(NetworkController.IconState.class),
+                mock(NetworkController.IconState.class),
+                0, 0, true, true, "", "", true, 0, true);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
index a8b169c..d4688d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java
@@ -16,13 +16,10 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.telephony.SubscriptionManager;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.testing.TestableLooper.RunWithLooper;
@@ -31,21 +28,16 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.keyguard.CarrierTextController.CarrierTextCallbackInfo;
 import com.android.systemui.R;
 import com.android.systemui.R.id;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.NetworkController;
 import com.android.systemui.utils.leaks.LeakCheckedTest;
 
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 @RunWith(AndroidTestingRunner.class)
 @RunWithLooper
@@ -77,117 +69,4 @@
         // Verify Settings wasn't launched.
         verify(mActivityStarter, never()).startActivity(any(), anyBoolean());
     }
-
-    @Test // throws no Exception
-    public void testUpdateCarrierText_sameLengts() {
-        QSFooterImpl spiedFooter = Mockito.spy(mFooter);
-        when(spiedFooter.getSlotIndex(anyInt())).thenAnswer(
-                new Answer<Integer>() {
-                    @Override
-                    public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
-                        return invocationOnMock.getArgument(0);
-                    }
-                });
-
-        // listOfCarriers length 1, subscriptionIds length 1, anySims false
-        CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{""},
-                false,
-                new int[]{0});
-        spiedFooter.updateCarrierInfo(c1);
-
-        // listOfCarriers length 1, subscriptionIds length 1, anySims true
-        CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{""},
-                true,
-                new int[]{0});
-        spiedFooter.updateCarrierInfo(c2);
-
-        // listOfCarriers length 2, subscriptionIds length 2, anySims false
-        CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{"", ""},
-                false,
-                new int[]{0, 1});
-        spiedFooter.updateCarrierInfo(c3);
-
-        // listOfCarriers length 2, subscriptionIds length 2, anySims true
-        CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{"", ""},
-                true,
-                new int[]{0, 1});
-        spiedFooter.updateCarrierInfo(c4);
-    }
-
-    @Test // throws no Exception
-    public void testUpdateCarrierText_differentLength() {
-        QSFooterImpl spiedFooter = Mockito.spy(mFooter);
-        when(spiedFooter.getSlotIndex(anyInt())).thenAnswer(
-                new Answer<Integer>() {
-                    @Override
-                    public Integer answer(InvocationOnMock invocationOnMock) throws Throwable {
-                        return invocationOnMock.getArgument(0);
-                    }
-                });
-
-        // listOfCarriers length 2, subscriptionIds length 1, anySims false
-        CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{"", ""},
-                false,
-                new int[]{0});
-        spiedFooter.updateCarrierInfo(c1);
-
-        // listOfCarriers length 2, subscriptionIds length 1, anySims true
-        CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{"", ""},
-                true,
-                new int[]{0});
-        spiedFooter.updateCarrierInfo(c2);
-
-        // listOfCarriers length 1, subscriptionIds length 2, anySims false
-        CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{""},
-                false,
-                new int[]{0, 1});
-        spiedFooter.updateCarrierInfo(c3);
-
-        // listOfCarriers length 1, subscriptionIds length 2, anySims true
-        CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{""},
-                true,
-                new int[]{0, 1});
-        spiedFooter.updateCarrierInfo(c4);
-    }
-
-    @Test // throws no Exception
-    public void testUpdateCarrierText_invalidSim() {
-        QSFooterImpl spiedFooter = Mockito.spy(mFooter);
-        when(spiedFooter.getSlotIndex(anyInt())).thenReturn(
-                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo(
-                "",
-                new CharSequence[]{"", ""},
-                true,
-                new int[]{0, 1});
-        spiedFooter.updateCarrierInfo(c4);
-    }
-
-    @Test // throws no Exception
-    public void testSetMobileDataIndicators_invalidSim() {
-        QSFooterImpl spiedFooter = Mockito.spy(mFooter);
-        when(spiedFooter.getSlotIndex(anyInt())).thenReturn(
-                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        spiedFooter.setMobileDataIndicators(
-                mock(NetworkController.IconState.class),
-                mock(NetworkController.IconState.class),
-                0, 0, true, true, "", "", true, 0, true);
-    }
-
 }