diff options
| author | 2021-12-01 00:23:53 +0000 | |
|---|---|---|
| committer | 2021-12-01 00:23:53 +0000 | |
| commit | e4f57c4994d43ab9f3c10cc8dfa650e8e29e0859 (patch) | |
| tree | b474f9df58bd9d4285a6c669f94d458d306bb94f | |
| parent | bcdaf0ce3aed85fd2ee4b1bfe1a55bcf2e3e7776 (diff) | |
Introduce communal trusted network condition.
This condition, when started, monitors Wi-Fi connections and reports
whether the device is currently connected to a trusted network.
Test: atest CommunalTrustedNetworkConditionTest
Bug: 202778351
Change-Id: Idcc93f9eb73075129ccba9b02b9ccb416ee07aaa
3 files changed, 240 insertions, 3 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalTrustedNetworkCondition.java b/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalTrustedNetworkCondition.java new file mode 100644 index 000000000000..c817979ee3c5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/communal/conditions/CommunalTrustedNetworkCondition.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2021 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.communal.conditions; + +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.net.wifi.WifiInfo; +import android.util.Log; + +import androidx.annotation.NonNull; + +import javax.inject.Inject; + +/** + * Monitors Wi-Fi connections and triggers callback, if any, when the device is connected to and + * disconnected from a trusted network. + */ +public class CommunalTrustedNetworkCondition extends CommunalCondition { + private final String mTag = getClass().getSimpleName(); + private final ConnectivityManager mConnectivityManager; + + @Inject + public CommunalTrustedNetworkCondition(ConnectivityManager connectivityManager) { + mConnectivityManager = connectivityManager; + } + + /** + * Starts monitoring for trusted network connection. Ignores if already started. + */ + @Override + protected void start() { + if (shouldLog()) Log.d(mTag, "start listening for wifi connections"); + + final NetworkRequest wifiNetworkRequest = new NetworkRequest.Builder().addTransportType( + NetworkCapabilities.TRANSPORT_WIFI).build(); + mConnectivityManager.registerNetworkCallback(wifiNetworkRequest, mNetworkCallback); + } + + /** + * Stops monitoring for trusted network connection. + */ + @Override + protected void stop() { + if (shouldLog()) Log.d(mTag, "stop listening for wifi connections"); + + mConnectivityManager.unregisterNetworkCallback(mNetworkCallback); + } + + private void updateWifiInfo(WifiInfo wifiInfo) { + // TODO(b/202778351): check whether wifi is trusted. + final boolean connectedToTrustedNetwork = wifiInfo != null; + + if (shouldLog()) { + Log.d(mTag, (connectedToTrustedNetwork ? "connected to" : "disconnected from") + + " a trusted network"); + } + + updateCondition(connectedToTrustedNetwork); + } + + private final ConnectivityManager.NetworkCallback mNetworkCallback = + new ConnectivityManager.NetworkCallback( + ConnectivityManager.NetworkCallback.FLAG_INCLUDE_LOCATION_INFO) { + private boolean mIsConnected = false; + private WifiInfo mWifiInfo; + + @Override + public void onAvailable(@NonNull Network network) { + super.onAvailable(network); + + if (shouldLog()) Log.d(mTag, "connected to wifi"); + + mIsConnected = true; + if (mWifiInfo != null) { + updateWifiInfo(mWifiInfo); + } + } + + @Override + public void onLost(@NonNull Network network) { + super.onLost(network); + + if (shouldLog()) Log.d(mTag, "disconnected from wifi"); + + mIsConnected = false; + mWifiInfo = null; + updateWifiInfo(null); + } + + @Override + public void onCapabilitiesChanged(@NonNull Network network, + @NonNull NetworkCapabilities networkCapabilities) { + super.onCapabilitiesChanged(network, networkCapabilities); + + mWifiInfo = (WifiInfo) networkCapabilities.getTransportInfo(); + + if (mIsConnected) { + updateWifiInfo(mWifiInfo); + } + } + }; + + private boolean shouldLog() { + return Log.isLoggable(mTag, Log.DEBUG); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java index 9b72655c9fb5..3ebfb513dfc5 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java +++ b/packages/SystemUI/src/com/android/systemui/communal/dagger/CommunalModule.java @@ -22,11 +22,12 @@ import android.widget.FrameLayout; import com.android.systemui.communal.conditions.CommunalCondition; import com.android.systemui.communal.conditions.CommunalSettingCondition; +import com.android.systemui.communal.conditions.CommunalTrustedNetworkCondition; import com.android.systemui.idle.AmbientLightModeMonitor; import com.android.systemui.idle.LightSensorEventsDebounceAlgorithm; import com.android.systemui.idle.dagger.IdleViewComponent; -import java.util.Collections; +import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -72,7 +73,9 @@ public interface CommunalModule { @ElementsIntoSet @Named(COMMUNAL_CONDITIONS) static Set<CommunalCondition> provideCommunalConditions( - CommunalSettingCondition communalSettingCondition) { - return new HashSet<>(Collections.singletonList(communalSettingCondition)); + CommunalSettingCondition communalSettingCondition, + CommunalTrustedNetworkCondition communalTrustedNetworkCondition) { + return new HashSet<>( + Arrays.asList(communalSettingCondition, communalTrustedNetworkCondition)); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalTrustedNetworkConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalTrustedNetworkConditionTest.java new file mode 100644 index 000000000000..a00c12b113a1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/communal/CommunalTrustedNetworkConditionTest.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2021 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.communal; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkRequest; +import android.net.wifi.WifiInfo; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.communal.conditions.CommunalTrustedNetworkCondition; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class CommunalTrustedNetworkConditionTest extends SysuiTestCase { + @Mock private ConnectivityManager mConnectivityManager; + + @Captor private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor; + + private CommunalTrustedNetworkCondition mCondition; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + mCondition = new CommunalTrustedNetworkCondition(mConnectivityManager); + } + + @Test + public void updateCallback_connectedToTrustedNetwork_reportsTrue() { + final CommunalTrustedNetworkCondition.Callback callback = + mock(CommunalTrustedNetworkCondition.Callback.class); + mCondition.addCallback(callback); + + final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback(); + + // Connected to Wi-Fi. + final Network network = mock(Network.class); + networkCallback.onAvailable(network); + networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities()); + + // Verifies that the callback is triggered. + verify(callback).onConditionChanged(mCondition, true); + } + + @Test + public void updateCallback_disconnectedFromTrustedNetwork_reportsFalse() { + final CommunalTrustedNetworkCondition.Callback callback = + mock(CommunalTrustedNetworkCondition.Callback.class); + mCondition.addCallback(callback); + + final ConnectivityManager.NetworkCallback networkCallback = captureNetworkCallback(); + + // Connected to Wi-Fi. + final Network network = mock(Network.class); + networkCallback.onAvailable(network); + networkCallback.onCapabilitiesChanged(network, fakeNetworkCapabilities()); + clearInvocations(callback); + + // Disconnected from Wi-Fi. + networkCallback.onLost(network); + + // Verifies that the callback is triggered. + verify(callback).onConditionChanged(mCondition, false); + } + + // Captures and returns the network callback, assuming it is registered with the connectivity + // manager. + private ConnectivityManager.NetworkCallback captureNetworkCallback() { + verify(mConnectivityManager).registerNetworkCallback(any(NetworkRequest.class), + mNetworkCallbackCaptor.capture()); + return mNetworkCallbackCaptor.getValue(); + } + + private NetworkCapabilities fakeNetworkCapabilities() { + final NetworkCapabilities networkCapabilities = mock(NetworkCapabilities.class); + final WifiInfo wifiInfo = mock(WifiInfo.class); + when(networkCapabilities.getTransportInfo()).thenReturn(wifiInfo); + return networkCapabilities; + } +} |