Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 370b0671 authored by yinxu's avatar yinxu
Browse files

Support VCN in SysUI

Bug: 175739479
Test: atest NetworkControllerWifiTest
Change-Id: I48caeac0e1f0a99c5848ec9cdf70a5830a700be0
parent 6d6a9489
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
package com.android.settingslib;

import android.annotation.ColorInt;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -23,6 +24,9 @@ import android.graphics.drawable.Drawable;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.os.BatteryManager;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -563,4 +567,21 @@ public class Utils {
        drawable.draw(canvas);
        return roundedBitmap;
    }

    /**
     * Returns the WifiInfo for the underlying WiFi network of the VCN network, returns null if the
     * input NetworkCapabilities is not for a VCN network with underlying WiFi network.
     *
     * @param networkCapabilities NetworkCapabilities of the network.
     */
    @Nullable
    public static WifiInfo tryGetWifiInfoForVcn(NetworkCapabilities networkCapabilities) {
        if (networkCapabilities.getTransportInfo() == null
                || !(networkCapabilities.getTransportInfo() instanceof VcnTransportInfo)) {
            return null;
        }
        VcnTransportInfo vcnTransportInfo =
                (VcnTransportInfo) networkCapabilities.getTransportInfo();
        return vcnTransportInfo.getWifiInfo();
    }
}
+21 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.provider.Settings;
import android.util.FeatureFlagUtils;

import com.android.settingslib.R;
import com.android.settingslib.Utils;

import java.util.List;

@@ -60,18 +61,26 @@ public class WifiStatusTracker {
    private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
            .clearCapabilities()
            .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).build();
    private final NetworkCallback mNetworkCallback = new NetworkCallback() {
        // Note: onCapabilitiesChanged is guaranteed to be called "immediately" after onAvailable
        // and onLinkPropertiesChanged.
        @Override
        public void onCapabilitiesChanged(
                Network network, NetworkCapabilities networkCapabilities) {
            WifiInfo wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
            WifiInfo wifiInfo = null;
            if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                wifiInfo = Utils.tryGetWifiInfoForVcn(networkCapabilities);
            } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                wifiInfo = (WifiInfo) networkCapabilities.getTransportInfo();
            }
            if (wifiInfo != null) {
                updateWifiInfo(wifiInfo);
                updateStatusLabel();
                mCallback.run();
            }
        }

        @Override
        public void onLost(Network network) {
@@ -238,8 +247,14 @@ public class WifiStatusTracker {
        NetworkCapabilities networkCapabilities;
        isDefaultNetwork = false;
        if (mDefaultNetworkCapabilities != null) {
            isDefaultNetwork = mDefaultNetworkCapabilities.hasTransport(
            boolean isWifi = mDefaultNetworkCapabilities.hasTransport(
                    NetworkCapabilities.TRANSPORT_WIFI);
            boolean isVcnOverWifi = mDefaultNetworkCapabilities.hasTransport(
                    NetworkCapabilities.TRANSPORT_CELLULAR)
                            && (Utils.tryGetWifiInfoForVcn(mDefaultNetworkCapabilities) != null);
            if (isWifi || isVcnOverWifi) {
                isDefaultNetwork = true;
            }
        }
        if (isDefaultNetwork) {
            // Wifi is connected and the default network.
+12 −3
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import androidx.annotation.NonNull;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.Utils;
import com.android.settingslib.mobile.MobileMappings.Config;
import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults;
import com.android.settingslib.mobile.TelephonyIcons;
@@ -919,12 +920,20 @@ public class NetworkControllerImpl extends BroadcastReceiver
        for (NetworkCapabilities nc :
                mConnectivityManager.getDefaultNetworkCapabilitiesForUser(mCurrentUserId)) {
            for (int transportType : nc.getTransportTypes()) {
                if (transportType == NetworkCapabilities.TRANSPORT_CELLULAR
                        && Utils.tryGetWifiInfoForVcn(nc) != null) {
                    mConnectedTransports.set(NetworkCapabilities.TRANSPORT_WIFI);
                    if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
                        mValidatedTransports.set(NetworkCapabilities.TRANSPORT_WIFI);
                    }
                } else {
                    mConnectedTransports.set(transportType);
                    if (nc.hasCapability(NET_CAPABILITY_VALIDATED)) {
                        mValidatedTransports.set(transportType);
                    }
                }
            }
        }

        if (mForceCellularValidated) mValidatedTransports.set(TRANSPORT_CELLULAR);

+44 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkScoreManager;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
@@ -182,6 +183,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
            if (rssi < -55) return 3;
            return 4;
        }).when(mMockWm).calculateSignalLevel(anyInt());
        when(mMockWm.getMaxSignalLevel()).thenReturn(4);

        mSignalStrength = mock(SignalStrength.class);
        mServiceState = mock(ServiceState.class);
@@ -308,6 +310,14 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
            NetworkCapabilities.TRANSPORT_CELLULAR, true, true);
    }

    public void setConnectivityViaBroadcastForVcn(
            int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
        mNetCapabilities.setTransportInfo(info);
        setConnectivityCommon(networkType, validated, isConnected);
        Intent i = new Intent(ConnectivityManager.INET_CONDITION_ACTION);
        mNetworkController.onReceive(mContext, i);
    }

    public void setConnectivityViaBroadcast(
        int networkType, boolean validated, boolean isConnected) {
        setConnectivityCommon(networkType, validated, isConnected);
@@ -341,6 +351,20 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
        }
    }

    public void setConnectivityViaCallbackInWifiTrackerForVcn(
            int networkType, boolean validated, boolean isConnected, VcnTransportInfo info) {
        mNetCapabilities.setTransportInfo(info);
        setConnectivityCommon(networkType, validated, isConnected);
        if (networkType == NetworkCapabilities.TRANSPORT_CELLULAR) {
            if (isConnected) {
                mNetworkCallback.onCapabilitiesChanged(
                        mock(Network.class), new NetworkCapabilities(mNetCapabilities));
            } else {
                mNetworkCallback.onLost(mock(Network.class));
            }
        }
    }

    public void setConnectivityViaDefaultCallbackInWifiTracker(
            int networkType, boolean validated, boolean isConnected, WifiInfo wifiInfo) {
        if (networkType == NetworkCapabilities.TRANSPORT_WIFI) {
@@ -509,6 +533,26 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
        assertEquals("Visibility in status bar", visible, iconState.visible);
    }

    protected void verifyLastMobileDataIndicatorsForVcn(boolean visible, int level, int typeIcon,
            boolean inet) {
        ArgumentCaptor<IconState> iconArg = ArgumentCaptor.forClass(IconState.class);
        ArgumentCaptor<Integer> typeIconArg = ArgumentCaptor.forClass(Integer.class);

        verify(mCallbackHandler, Mockito.atLeastOnce()).setMobileDataIndicators(
                iconArg.capture(),
                any(),
                typeIconArg.capture(),
                anyInt(), anyBoolean(), anyBoolean(),
                any(CharSequence.class), any(CharSequence.class), any(),
                anyBoolean(), anyInt(), anyBoolean());
        IconState iconState = iconArg.getValue();
        int state = SignalDrawable.getState(
                level, CellSignalStrength.getNumSignalStrengthLevels(), !inet);
        assertEquals("Signal icon in status bar", state, iconState.icon);
        assertEquals("Data icon in status bar", typeIcon, (int) typeIconArg.getValue());
        assertEquals("Visibility in status bar", visible, iconState.visible);
    }

    protected void verifyLastMobileDataIndicators(boolean visible, int icon, int typeIcon,
            boolean qsVisible, int qsIcon, int qsTypeIcon, boolean dataIn, boolean dataOut) {
        verifyLastMobileDataIndicators(
+51 −0
Original line number Diff line number Diff line
@@ -12,12 +12,14 @@ import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.vcn.VcnTransportInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;

import com.android.settingslib.mobile.TelephonyIcons;
import com.android.systemui.statusbar.policy.NetworkController.IconState;

import org.junit.Before;
@@ -34,6 +36,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
    private static final int MIN_RSSI = -100;
    private static final int MAX_RSSI = -55;
    private WifiInfo mWifiInfo = mock(WifiInfo.class);
    private VcnTransportInfo mVcnTransportInfo = mock(VcnTransportInfo.class);

    @Before
    public void setUp() throws Exception {
@@ -214,6 +217,32 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
        assertEquals(testSsid, mNetworkController.mWifiSignalController.mCurrentState.ssid);
    }

    @Test
    public void testVcnWithUnderlyingWifi() {
        String testSsid = "Test VCN SSID";
        setWifiEnabled(true);
        verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);

        setWifiStateForVcn(true, testSsid);
        setWifiLevelForVcn(0);

        // Connected, but still not validated - does not show
        //verifyLastWifiIcon(false, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
        verifyLastMobileDataIndicatorsForVcn(false, 0, TelephonyIcons.ICON_CWF, false);

        for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
            setWifiLevelForVcn(testLevel);

            setConnectivityViaBroadcastForVcn(
                    NetworkCapabilities.TRANSPORT_CELLULAR, true, true, mVcnTransportInfo);
            verifyLastMobileDataIndicatorsForVcn(true, testLevel, TelephonyIcons.ICON_CWF, true);

            setConnectivityViaBroadcastForVcn(
                    NetworkCapabilities.TRANSPORT_CELLULAR, false, true, mVcnTransportInfo);
            verifyLastMobileDataIndicatorsForVcn(false, testLevel, TelephonyIcons.ICON_CWF, false);
        }
    }

    protected void setWifiActivity(int activity) {
        // TODO: Not this, because this variable probably isn't sticking around.
        mNetworkController.mWifiSignalController.setActivity(activity);
@@ -241,6 +270,28 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
                NetworkCapabilities.TRANSPORT_WIFI, false, connected, mWifiInfo);
    }

    protected void setWifiLevelForVcn(int level) {
        float amountPerLevel = (MAX_RSSI - MIN_RSSI) / (WifiIcons.WIFI_LEVEL_COUNT - 1);
        int rssi = (int) (MIN_RSSI + level * amountPerLevel);
        // Put RSSI in the middle of the range.
        rssi += amountPerLevel / 2;
        when(mVcnTransportInfo.getWifiInfo()).thenReturn(mWifiInfo);
        when(mWifiInfo.getRssi()).thenReturn(rssi);
        when(mWifiInfo.isCarrierMerged()).thenReturn(true);
        when(mWifiInfo.getSubscriptionId()).thenReturn(1);
        setConnectivityViaCallbackInWifiTrackerForVcn(
                NetworkCapabilities.TRANSPORT_CELLULAR, false, true, mVcnTransportInfo);
    }

    protected void setWifiStateForVcn(boolean connected, String ssid) {
        when(mVcnTransportInfo.getWifiInfo()).thenReturn(mWifiInfo);
        when(mWifiInfo.getSSID()).thenReturn(ssid);
        when(mWifiInfo.isCarrierMerged()).thenReturn(true);
        when(mWifiInfo.getSubscriptionId()).thenReturn(1);
        setConnectivityViaCallbackInWifiTrackerForVcn(
                NetworkCapabilities.TRANSPORT_CELLULAR, false, connected, mVcnTransportInfo);
    }

    protected void verifyLastQsDataDirection(boolean in, boolean out) {
        ArgumentCaptor<Boolean> inArg = ArgumentCaptor.forClass(Boolean.class);
        ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);