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

Commit d1933210 authored by Darrell Shi's avatar Darrell Shi
Browse files

Check whether a Wi-Fi network is trusted.

When a Wi-Fi network is connected, check if it's in the trusted listed
set by settings. Only when the network is trusted should the condition
be fulfilled.

Test: atest CommunalTrustedNetworkConditionTest
Bug: 202778351
Change-Id: Ib975d5a7d3d687b5978d3eddcfa22a9bfef97236
parent e4f57c49
Loading
Loading
Loading
Loading
+70 −3
Original line number Original line Diff line number Diff line
@@ -16,15 +16,26 @@


package com.android.systemui.communal.conditions;
package com.android.systemui.communal.conditions;


import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.util.Log;


import androidx.annotation.NonNull;
import androidx.annotation.NonNull;


import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.util.settings.SecureSettings;

import java.util.Arrays;
import java.util.HashSet;

import javax.inject.Inject;
import javax.inject.Inject;


/**
/**
@@ -34,10 +45,32 @@ import javax.inject.Inject;
public class CommunalTrustedNetworkCondition extends CommunalCondition {
public class CommunalTrustedNetworkCondition extends CommunalCondition {
    private final String mTag = getClass().getSimpleName();
    private final String mTag = getClass().getSimpleName();
    private final ConnectivityManager mConnectivityManager;
    private final ConnectivityManager mConnectivityManager;
    private final ContentObserver mTrustedNetworksObserver;
    private final SecureSettings mSecureSettings;

    // The SSID of the connected Wi-Fi network. Null if not connected to Wi-Fi.
    private String mWifiSSID;

    // Set of SSIDs of trusted networks.
    private final HashSet<String> mTrustedNetworks = new HashSet<>();

    /**
     * The deliminator used to separate trusted network keys saved as a string in secure settings.
     */
    public static final String SETTINGS_STRING_DELIMINATOR = ",/";


    @Inject
    @Inject
    public CommunalTrustedNetworkCondition(ConnectivityManager connectivityManager) {
    public CommunalTrustedNetworkCondition(@Main Handler handler,
            ConnectivityManager connectivityManager, SecureSettings secureSettings) {
        mConnectivityManager = connectivityManager;
        mConnectivityManager = connectivityManager;
        mSecureSettings = secureSettings;

        mTrustedNetworksObserver = new ContentObserver(handler) {
            @Override
            public void onChange(boolean selfChange) {
                fetchTrustedNetworks();
            }
        };
    }
    }


    /**
    /**
@@ -47,9 +80,14 @@ public class CommunalTrustedNetworkCondition extends CommunalCondition {
    protected void start() {
    protected void start() {
        if (shouldLog()) Log.d(mTag, "start listening for wifi connections");
        if (shouldLog()) Log.d(mTag, "start listening for wifi connections");


        fetchTrustedNetworks();

        final NetworkRequest wifiNetworkRequest = new NetworkRequest.Builder().addTransportType(
        final NetworkRequest wifiNetworkRequest = new NetworkRequest.Builder().addTransportType(
                NetworkCapabilities.TRANSPORT_WIFI).build();
                NetworkCapabilities.TRANSPORT_WIFI).build();
        mConnectivityManager.registerNetworkCallback(wifiNetworkRequest, mNetworkCallback);
        mConnectivityManager.registerNetworkCallback(wifiNetworkRequest, mNetworkCallback);
        mSecureSettings.registerContentObserverForUser(
                Settings.Secure.COMMUNAL_MODE_TRUSTED_NETWORKS, false, mTrustedNetworksObserver,
                UserHandle.USER_SYSTEM);
    }
    }


    /**
    /**
@@ -60,11 +98,40 @@ public class CommunalTrustedNetworkCondition extends CommunalCondition {
        if (shouldLog()) Log.d(mTag, "stop listening for wifi connections");
        if (shouldLog()) Log.d(mTag, "stop listening for wifi connections");


        mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
        mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
        mSecureSettings.unregisterContentObserver(mTrustedNetworksObserver);
    }
    }


    private void updateWifiInfo(WifiInfo wifiInfo) {
    private void updateWifiInfo(WifiInfo wifiInfo) {
        // TODO(b/202778351): check whether wifi is trusted.
        if (wifiInfo == null) {
        final boolean connectedToTrustedNetwork = wifiInfo != null;
            mWifiSSID = null;
        } else {
            // Remove the wrapping quotes around the SSID.
            mWifiSSID = wifiInfo.getSSID().replace("\"", "");
        }

        checkIfConnectedToTrustedNetwork();
    }

    private void fetchTrustedNetworks() {
        final String trustedNetworksString = mSecureSettings.getStringForUser(
                Settings.Secure.COMMUNAL_MODE_TRUSTED_NETWORKS, UserHandle.USER_SYSTEM);
        mTrustedNetworks.clear();

        if (shouldLog()) Log.d(mTag, "fetched trusted networks: " + trustedNetworksString);

        if (TextUtils.isEmpty(trustedNetworksString)) {
            return;
        }

        mTrustedNetworks.addAll(
                Arrays.asList(trustedNetworksString.split(SETTINGS_STRING_DELIMINATOR)));

        checkIfConnectedToTrustedNetwork();
    }

    private void checkIfConnectedToTrustedNetwork() {
        final boolean connectedToTrustedNetwork = mWifiSSID != null && mTrustedNetworks.contains(
                mWifiSSID);


        if (shouldLog()) {
        if (shouldLog()) {
            Log.d(mTag, (connectedToTrustedNetwork ? "connected to" : "disconnected from")
            Log.d(mTag, (connectedToTrustedNetwork ? "connected to" : "disconnected from")
+66 −6
Original line number Original line Diff line number Diff line
@@ -16,9 +16,12 @@


package com.android.systemui.communal;
package com.android.systemui.communal;


import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;


@@ -27,12 +30,18 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.provider.Settings;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;


import androidx.test.filters.SmallTest;
import androidx.test.filters.SmallTest;


import com.android.systemui.SysuiTestCase;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.communal.conditions.CommunalTrustedNetworkCondition;
import com.android.systemui.communal.conditions.CommunalTrustedNetworkCondition;
import com.android.systemui.util.settings.FakeSettings;
import com.android.systemui.utils.os.FakeHandler;


import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
@@ -49,12 +58,21 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase {


    @Captor private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor;
    @Captor private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor;


    private final Handler mHandler = new FakeHandler(Looper.getMainLooper());
    private CommunalTrustedNetworkCondition mCondition;
    private CommunalTrustedNetworkCondition mCondition;


    private final String mTrustedWifi1 = "wifi-1";
    private final String mTrustedWifi2 = "wifi-2";

    @Before
    @Before
    public void setup() {
    public void setup() {
        MockitoAnnotations.initMocks(this);
        MockitoAnnotations.initMocks(this);
        mCondition = new CommunalTrustedNetworkCondition(mConnectivityManager);
        final FakeSettings secureSettings = new FakeSettings();
        secureSettings.putStringForUser(Settings.Secure.COMMUNAL_MODE_TRUSTED_NETWORKS,
                mTrustedWifi1 + CommunalTrustedNetworkCondition.SETTINGS_STRING_DELIMINATOR
                        + mTrustedWifi2, UserHandle.USER_SYSTEM);
        mCondition = new CommunalTrustedNetworkCondition(mHandler, mConnectivityManager,
                secureSettings);
    }
    }


    @Test
    @Test
@@ -65,17 +83,58 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase {


        final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback();
        final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback();


        // Connected to Wi-Fi.
        // Connected to trusted Wi-Fi network.
        final Network network = mock(Network.class);
        final Network network = mock(Network.class);
        networkCallback.onAvailable(network);
        networkCallback.onAvailable(network);
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities());
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1));


        // Verifies that the callback is triggered.
        // Verifies that the callback is triggered.
        verify(callback).onConditionChanged(mCondition, true);
        verify(callback).onConditionChanged(mCondition, true);
    }
    }


    @Test
    @Test
    public void updateCallback_disconnectedFromTrustedNetwork_reportsFalse() {
    public void updateCallback_switchedToAnotherTrustedNetwork_reportsNothing() {
        final CommunalTrustedNetworkCondition.Callback callback =
                mock(CommunalTrustedNetworkCondition.Callback.class);
        mCondition.addCallback(callback);

        final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback();

        // Connected to a trusted Wi-Fi network.
        final Network network = mock(Network.class);
        networkCallback.onAvailable(network);
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1));
        clearInvocations(callback);

        // Connected to another trusted Wi-Fi network.
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi2));

        // Verifies that the callback is not triggered.
        verify(callback, never()).onConditionChanged(eq(mCondition), anyBoolean());
    }

    @Test
    public void updateCallback_connectedToNonTrustedNetwork_reportsFalse() {
        final CommunalTrustedNetworkCondition.Callback callback =
                mock(CommunalTrustedNetworkCondition.Callback.class);
        mCondition.addCallback(callback);

        final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback();

        // Connected to trusted Wi-Fi network.
        final Network network = mock(Network.class);
        networkCallback.onAvailable(network);
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1));

        // Connected to non-trusted Wi-Fi network.
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities("random-wifi"));

        // Verifies that the callback is triggered.
        verify(callback).onConditionChanged(mCondition, false);
    }

    @Test
    public void updateCallback_disconnectedFromNetwork_reportsFalse() {
        final CommunalTrustedNetworkCondition.Callback callback =
        final CommunalTrustedNetworkCondition.Callback callback =
                mock(CommunalTrustedNetworkCondition.Callback.class);
                mock(CommunalTrustedNetworkCondition.Callback.class);
        mCondition.addCallback(callback);
        mCondition.addCallback(callback);
@@ -85,7 +144,7 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase {
        // Connected to Wi-Fi.
        // Connected to Wi-Fi.
        final Network network = mock(Network.class);
        final Network network = mock(Network.class);
        networkCallback.onAvailable(network);
        networkCallback.onAvailable(network);
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities());
        networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities(mTrustedWifi1));
        clearInvocations(callback);
        clearInvocations(callback);


        // Disconnected from Wi-Fi.
        // Disconnected from Wi-Fi.
@@ -103,9 +162,10 @@ public class CommunalTrustedNetworkConditionTest extends SysuiTestCase {
        return mNetworkCallbackCaptor.getValue();
        return mNetworkCallbackCaptor.getValue();
    }
    }


    private NetworkCapabilities fakeNetworkCapabilities() {
    private NetworkCapabilities fakeNetworkCapabilities(String ssid) {
        final NetworkCapabilities networkCapabilities = mock(NetworkCapabilities.class);
        final NetworkCapabilities networkCapabilities = mock(NetworkCapabilities.class);
        final WifiInfo wifiInfo = mock(WifiInfo.class);
        final WifiInfo wifiInfo = mock(WifiInfo.class);
        when(wifiInfo.getSSID()).thenReturn(ssid);
        when(networkCapabilities.getTransportInfo()).thenReturn(wifiInfo);
        when(networkCapabilities.getTransportInfo()).thenReturn(wifiInfo);
        return networkCapabilities;
        return networkCapabilities;
    }
    }