blob: bb4b0c414923a8faf2e57cfc397b25557e9516bd [file] [log] [blame]
/*
* 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.settings.network;
import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static com.android.settings.network.TetherEnabler.TETHERING_BLUETOOTH_ON;
import static com.android.settings.network.TetherEnabler.TETHERING_ETHERNET_ON;
import static com.android.settings.network.TetherEnabler.TETHERING_OFF;
import static com.android.settings.network.TetherEnabler.TETHERING_USB_ON;
import static com.android.settings.network.TetherEnabler.TETHERING_WIFI_ON;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothPan;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkPolicyManager;
import android.net.TetheringManager;
import android.net.wifi.WifiManager;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.network.TetherEnabler.OnTetherStateUpdateListener;
import com.android.settings.widget.SwitchBar;
import com.android.settings.widget.SwitchBarController;
import com.android.settings.widget.SwitchWidgetController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.util.ReflectionHelpers;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@RunWith(RobolectricTestRunner.class)
public class TetherEnablerTest {
@Mock
private WifiManager mWifiManager;
@Mock
private ConnectivityManager mConnectivityManager;
@Mock
private TetheringManager mTetheringManager;
@Mock
private NetworkPolicyManager mNetworkPolicyManager;
@Mock
private BluetoothPan mBluetoothPan;
@Mock
private BluetoothAdapter mBluetoothAdapter;
private SwitchBar mSwitchBar;
private TetherEnabler mEnabler;
private SwitchWidgetController mSwitchWidgetController;
private static final String[] USB_TETHERED = {"usb"};
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Context context = spy(ApplicationProvider.getApplicationContext());
AtomicReference<BluetoothPan> panReference = spy(AtomicReference.class);
mSwitchBar = spy(new SwitchBar(context));
mSwitchWidgetController = spy(new SwitchBarController(mSwitchBar));
when(context.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager);
when(context.getSystemService(Context.CONNECTIVITY_SERVICE)).thenReturn(
mConnectivityManager);
when(context.getSystemService(Context.TETHERING_SERVICE)).thenReturn(mTetheringManager);
when(context.getSystemService(Context.NETWORK_POLICY_SERVICE)).thenReturn(
mNetworkPolicyManager);
when(mTetheringManager.getTetherableIfaces()).thenReturn(new String[0]);
when(mTetheringManager.getTetheredIfaces()).thenReturn(new String[0]);
when(mTetheringManager.getTetherableUsbRegexs()).thenReturn(new String[0]);
panReference.set(mBluetoothPan);
mEnabler = spy(new TetherEnabler(context, mSwitchWidgetController, panReference));
ReflectionHelpers.setField(mEnabler, "mBluetoothAdapter", mBluetoothAdapter);
}
@Test
public void lifecycle_onStart_setCheckedCorrectly() {
when(mTetheringManager.getTetheredIfaces()).thenReturn(USB_TETHERED);
when(mTetheringManager.getTetherableUsbRegexs()).thenReturn(USB_TETHERED);
mEnabler.onStart();
assertThat(mSwitchBar.isChecked()).isTrue();
}
@Test
public void lifecycle_onStart_shoudRegisterTetheringEventCallback() {
mEnabler.onStart();
verify(mTetheringManager).registerTetheringEventCallback(any(),
eq(mEnabler.mTetheringEventCallback));
}
@Test
public void lifecycle_onStop_shouldUnregisterTetheringEventCallback() {
mEnabler.onStart();
TetheringManager.TetheringEventCallback callback = mEnabler.mTetheringEventCallback;
mEnabler.onStop();
verify(mTetheringManager).unregisterTetheringEventCallback(callback);
assertThat(mEnabler.mTetheringEventCallback).isNull();
}
@Test
public void lifecycle_onStop_resetBluetoothTetheringStoppedByUser() {
mEnabler.onStart();
mEnabler.mBluetoothTetheringStoppedByUser = true;
mEnabler.onStop();
assertThat(mEnabler.mBluetoothTetheringStoppedByUser).isFalse();
}
@Test
public void startTether_fail_resetSwitchBar() {
when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(false);
mEnabler.onStart();
mEnabler.startTethering(TetheringManager.TETHERING_WIFI);
when(mTetheringManager.getTetheredIfaces()).thenReturn(new String[0]);
mEnabler.mOnStartTetheringCallback.onTetheringFailed();
assertThat(mSwitchBar.isChecked()).isFalse();
assertThat(mSwitchBar.isEnabled()).isTrue();
}
@Test
public void onDataSaverChanged_setsEnabledCorrectly() {
mSwitchBar.setEnabled(true);
// try to turn data saver on
when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(true);
mEnabler.onDataSaverChanged(true);
assertThat(mSwitchBar.isEnabled()).isFalse();
// lets turn data saver off again
when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(false);
mEnabler.onDataSaverChanged(false);
assertThat(mSwitchBar.isEnabled()).isTrue();
}
@Test
public void onSwitchToggled_onlyStartsWifiTetherWhenNeeded() {
doReturn(TETHERING_WIFI_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(true);
verify(mConnectivityManager, never()).startTethering(anyInt(), anyBoolean(), any(), any());
doReturn(TETHERING_OFF).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(true);
verify(mConnectivityManager).startTethering(eq(TETHERING_WIFI), anyBoolean(), any(), any());
verify(mConnectivityManager, never()).startTethering(eq(TETHERING_USB), anyBoolean(), any(),
any());
verify(mConnectivityManager, never()).startTethering(eq(TETHERING_BLUETOOTH), anyBoolean(),
any(), any());
verify(mConnectivityManager, never()).startTethering(eq(TETHERING_ETHERNET), anyBoolean(),
any(), any());
}
@Test
public void onSwitchToggled_stopAllTetheringInterfaces() {
mEnabler.onStart();
doReturn(TETHERING_WIFI_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(false);
verify(mConnectivityManager).stopTethering(TETHERING_WIFI);
doReturn(TETHERING_USB_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(false);
verify(mConnectivityManager).stopTethering(TETHERING_USB);
doReturn(TETHERING_BLUETOOTH_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(false);
verify(mConnectivityManager).stopTethering(TETHERING_BLUETOOTH);
doReturn(TETHERING_ETHERNET_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.onSwitchToggled(false);
verify(mConnectivityManager).stopTethering(TETHERING_ETHERNET);
}
@Test
public void startTethering_startsBluetoothTetherWhenOff() {
when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_OFF);
mEnabler.startTethering(ConnectivityManager.TETHERING_BLUETOOTH);
verify(mBluetoothAdapter).enable();
when(mBluetoothAdapter.getState()).thenReturn(BluetoothAdapter.STATE_ON);
mEnabler.startTethering(ConnectivityManager.TETHERING_BLUETOOTH);
verify(mConnectivityManager).startTethering(
eq(ConnectivityManager.TETHERING_BLUETOOTH), anyBoolean(), any(), any());
}
@Test
public void stopTethering_setBluetoothTetheringStoppedByUserAndUpdateState() {
mSwitchWidgetController.setListener(mEnabler);
mSwitchWidgetController.startListening();
doReturn(TETHERING_BLUETOOTH_ON).when(mEnabler).getTetheringState(null /* tethered */);
mEnabler.stopTethering(TetheringManager.TETHERING_BLUETOOTH);
assertThat(mEnabler.mBluetoothTetheringStoppedByUser).isTrue();
verify(mEnabler).updateState(null);
}
@Test
public void updateState_onSwitchToggleNeverCalled() {
mSwitchWidgetController.setListener(mEnabler);
mSwitchWidgetController.startListening();
mEnabler.updateState(null /* tethered */);
verify(mEnabler, never()).onSwitchToggled(anyBoolean());
}
@Test
public void updateState_shouldEnableSwitchBarNotTethering() {
mSwitchWidgetController.setListener(mEnabler);
mSwitchWidgetController.startListening();
ReflectionHelpers.setField(mEnabler, "mDataSaverEnabled", false);
mEnabler.updateState(null/*tethered*/);
verify(mSwitchBar).setEnabled(true);
}
@Test
public void updateState_shouldEnableSwitchBarTethering() {
when(mTetheringManager.getTetheredIfaces()).thenReturn(USB_TETHERED);
when(mTetheringManager.getTetherableUsbRegexs()).thenReturn(USB_TETHERED);
mSwitchWidgetController.setListener(mEnabler);
mSwitchWidgetController.startListening();
ReflectionHelpers.setField(mEnabler, "mDataSaverEnabled", false);
mEnabler.updateState(null/*tethered*/);
verify(mSwitchBar).setEnabled(true);
}
@Test
public void updateState_shouldCallListener() {
OnTetherStateUpdateListener listener = mock(
OnTetherStateUpdateListener.class);
List<OnTetherStateUpdateListener> listeners = new ArrayList<>();
listeners.add(listener);
ReflectionHelpers.setField(mEnabler, "mListeners", listeners);
mSwitchWidgetController.setListener(mEnabler);
mSwitchWidgetController.startListening();
mEnabler.updateState(null /* tethered */);
verify(listener).onTetherStateUpdated(anyInt());
}
@Test
public void addListener_listenerShouldAdded() {
OnTetherStateUpdateListener listener = mock(
OnTetherStateUpdateListener.class);
mEnabler.addListener(listener);
assertThat(mEnabler.mListeners).contains(listener);
}
@Test
public void remListener_listenerShouldBeRemoved() {
OnTetherStateUpdateListener listener = mock(
OnTetherStateUpdateListener.class);
mEnabler.removeListener(listener);
assertThat(mEnabler.mListeners).doesNotContain(listener);
}
@Test
public void isTethering_shouldReturnCorrectly() {
assertThat(TetherEnabler.isTethering(TETHERING_WIFI_ON, TETHERING_WIFI)).isTrue();
assertThat(TetherEnabler.isTethering(~TETHERING_WIFI_ON, TETHERING_WIFI)).isFalse();
assertThat(TetherEnabler.isTethering(TETHERING_USB_ON, TETHERING_USB)).isTrue();
assertThat(TetherEnabler.isTethering(~TETHERING_USB_ON, TETHERING_USB)).isFalse();
assertThat(TetherEnabler.isTethering(TETHERING_BLUETOOTH_ON, TETHERING_BLUETOOTH)).isTrue();
assertThat(TetherEnabler.isTethering(~TETHERING_BLUETOOTH_ON, TETHERING_BLUETOOTH))
.isFalse();
assertThat(TetherEnabler.isTethering(TETHERING_ETHERNET_ON, TETHERING_ETHERNET)).isTrue();
assertThat(TetherEnabler.isTethering(~TETHERING_ETHERNET_ON, TETHERING_ETHERNET)).isFalse();
}
}