Loading services/core/java/com/android/server/connectivity/Tethering.java +30 −33 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static com.android.server.ConnectivityService.SHORT_ARG; Loading Loading @@ -89,6 +90,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.UserManagerInternal.UserRestrictionsListener; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; Loading @@ -97,7 +100,6 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; Loading Loading @@ -182,12 +184,13 @@ public class Tethering extends BaseNetworkObserver { // into a single coherent structure. private final HashSet<IpServer> mForwardedDownstreams; private final VersionedBroadcastListener mCarrierConfigChange; private final VersionedBroadcastListener mDefaultSubscriptionChange; private final TetheringDependencies mDeps; private final EntitlementManager mEntitlementMgr; private final Handler mHandler; private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks = new RemoteCallbackList<>(); private final PhoneStateListener mPhoneStateListener; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; Loading Loading @@ -238,7 +241,6 @@ public class Tethering extends BaseNetworkObserver { stopTethering(downstream); }); mEntitlementMgr.setTetheringConfigurationFetcher(() -> { maybeDefaultDataSubChanged(); return mConfig; }); Loading @@ -250,14 +252,16 @@ public class Tethering extends BaseNetworkObserver { mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); }); filter = new IntentFilter(); filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); mDefaultSubscriptionChange = new VersionedBroadcastListener( "DefaultSubscriptionChangeListener", mContext, mHandler, filter, (Intent ignored) -> { mLog.log("OBSERVED default data subscription change"); maybeDefaultDataSubChanged(); // To avoid launch unexpected provisioning checks, ignore re-provisioning when mPhoneStateListener = new PhoneStateListener(mLooper) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId + " to " + subId); if (subId == mActiveDataSubId) return; mActiveDataSubId = subId; updateConfiguration(); // To avoid launching unexpected provisioning checks, ignore re-provisioning when // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be // triggered again when CarrierConfig is loaded. if (mEntitlementMgr.getCarrierConfig(mConfig) != null) { Loading @@ -265,7 +269,9 @@ public class Tethering extends BaseNetworkObserver { } else { mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded"); } }); } }; mStateReceiver = new StateReceiver(); // Load tethering configuration. Loading @@ -276,7 +282,8 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters(Handler handler) { mCarrierConfigChange.startListening(); mDefaultSubscriptionChange.startListening(); TelephonyManager.from(mContext).listen(mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_STATE); Loading Loading @@ -304,27 +311,17 @@ public class Tethering extends BaseNetworkObserver { // NOTE: This is always invoked on the mLooper thread. private void updateConfiguration() { final int subId = mDeps.getDefaultDataSubscriptionId(); updateConfiguration(subId); } private void updateConfiguration(final int subId) { mConfig = new TetheringConfiguration(mContext, mLog, subId); mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId); mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); } private void maybeDunSettingChanged() { final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext); final boolean isDunRequired = TetheringConfiguration.checkDunRequired( mContext, mActiveDataSubId); if (isDunRequired == mConfig.isDunRequired) return; updateConfiguration(); } private void maybeDefaultDataSubChanged() { final int subId = mDeps.getDefaultDataSubscriptionId(); if (subId == mConfig.subId) return; updateConfiguration(subId); } @Override public void interfaceStatusChanged(String iface, boolean up) { // Never called directly: only called from interfaceLinkStateChanged. Loading services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +3 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public class TetheringConfiguration { tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs); tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); isDunRequired = checkDunRequired(ctx); isDunRequired = checkDunRequired(ctx, subId); chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic); preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired); Loading Loading @@ -228,9 +228,9 @@ public class TetheringConfiguration { } /** Check whether dun is required. */ public static boolean checkDunRequired(Context ctx) { public static boolean checkDunRequired(Context ctx, int id) { final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE); return (tm != null) ? tm.getTetherApnRequired() : false; return (tm != null) ? tm.getTetherApnRequired(id) : false; } private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { Loading services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +4 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.os.Handler; import android.telephony.SubscriptionManager; import com.android.internal.util.StateMachine; import com.android.server.connectivity.MockableSystemProperties; Loading Loading @@ -88,9 +87,10 @@ public class TetheringDependencies { } /** * Get default data subscription id to build TetheringConfiguration. * Generate a new TetheringConfiguration according to input sub Id. */ public int getDefaultDataSubscriptionId() { return SubscriptionManager.getDefaultDataSubscriptionId(); public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, int subId) { return new TetheringConfiguration(ctx, log, subId); } } tests/net/java/com/android/server/connectivity/TetheringTest.java +37 −2 Original line number Diff line number Diff line Loading @@ -100,6 +100,8 @@ import android.os.UserManager; import android.os.test.TestLooper; import android.provider.Settings; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.test.mock.MockContentResolver; import androidx.test.filters.SmallTest; Loading @@ -111,6 +113,7 @@ import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; import com.android.server.connectivity.tethering.OffloadHardwareInterface; import com.android.server.connectivity.tethering.TetheringConfiguration; import com.android.server.connectivity.tethering.TetheringDependencies; import com.android.server.connectivity.tethering.UpstreamNetworkMonitor; Loading @@ -118,6 +121,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading Loading @@ -147,6 +151,7 @@ public class TetheringTest { @Mock private MockableSystemProperties mSystemProperties; @Mock private OffloadHardwareInterface mOffloadHardwareInterface; @Mock private Resources mResources; @Mock private TelephonyManager mTelephonyManager; @Mock private UsbManager mUsbManager; @Mock private WifiManager mWifiManager; @Mock private CarrierConfigManager mCarrierConfigManager; Loading @@ -171,6 +176,7 @@ public class TetheringTest { private MockContentResolver mContentResolver; private BroadcastReceiver mBroadcastReceiver; private Tethering mTethering; private PhoneStateListener mPhoneStateListener; private class MockContext extends BroadcastInterceptingContext { MockContext(Context base) { Loading @@ -193,6 +199,7 @@ public class TetheringTest { public Object getSystemService(String name) { if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; if (Context.USB_SERVICE.equals(name)) return mUsbManager; if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; return super.getSystemService(name); } } Loading Loading @@ -234,6 +241,17 @@ public class TetheringTest { } } private class MockTetheringConfiguration extends TetheringConfiguration { MockTetheringConfiguration(Context ctx, SharedLog log, int id) { super(ctx, log, id); } @Override protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { return mResources; } } public class MockTetheringDependencies extends TetheringDependencies { StateMachine upstreamNetworkMonitorMasterSM; ArrayList<IpServer> ipv6CoordinatorNotifyList; Loading Loading @@ -276,8 +294,9 @@ public class TetheringTest { } @Override public int getDefaultDataSubscriptionId() { return INVALID_SUBSCRIPTION_ID; public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, int subId) { return new MockTetheringConfiguration(ctx, log, subId); } } Loading Loading @@ -372,6 +391,11 @@ public class TetheringTest { mTetheringDependencies.reset(); mTethering = makeTethering(); verify(mNMService).registerTetheringStatsProvider(any(), anyString()); final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = ArgumentCaptor.forClass(PhoneStateListener.class); verify(mTelephonyManager).listen(phoneListenerCaptor.capture(), eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)); mPhoneStateListener = phoneListenerCaptor.getValue(); } private Tethering makeTethering() { Loading Loading @@ -982,6 +1006,17 @@ public class TetheringTest { callback2.expectUpstreamChanged(upstreamState.network); } @Test public void testMultiSimAware() throws Exception { final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId); final int fakeSubId = 1234; mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); assertEquals(fakeSubId, newConfig.subId); } // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. } tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +6 −5 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.internal.R.array.config_tether_upstream_types; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.when; import android.content.ContentResolver; Loading Loading @@ -141,7 +142,7 @@ public class TetheringConfigurationTest { @Test public void testDunFromTelephonyManagerMeansDun() { when(mTelephonyManager.getTetherApnRequired()).thenReturn(true); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(true); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( Loading @@ -165,7 +166,7 @@ public class TetheringConfigurationTest { @Test public void testDunNotRequiredFromTelephonyManagerMeansNoDun() { when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( Loading Loading @@ -208,7 +209,7 @@ public class TetheringConfigurationTest { @Test public void testNoDefinedUpstreamTypesAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading @@ -231,7 +232,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesSansEthernetAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading @@ -249,7 +250,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() { when(mResources.getIntArray(config_tether_upstream_types)) .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading Loading
services/core/java/com/android/server/connectivity/Tethering.java +30 −33 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.IFACE_IP_MODE_UNSPECIFIED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED; import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED; import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID; import static com.android.server.ConnectivityService.SHORT_ARG; Loading Loading @@ -89,6 +90,8 @@ import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; import android.os.UserManagerInternal.UserRestrictionsListener; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; Loading @@ -97,7 +100,6 @@ import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.util.DumpUtils; import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.MessageUtils; Loading Loading @@ -182,12 +184,13 @@ public class Tethering extends BaseNetworkObserver { // into a single coherent structure. private final HashSet<IpServer> mForwardedDownstreams; private final VersionedBroadcastListener mCarrierConfigChange; private final VersionedBroadcastListener mDefaultSubscriptionChange; private final TetheringDependencies mDeps; private final EntitlementManager mEntitlementMgr; private final Handler mHandler; private final RemoteCallbackList<ITetheringEventCallback> mTetheringEventCallbacks = new RemoteCallbackList<>(); private final PhoneStateListener mPhoneStateListener; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; private volatile TetheringConfiguration mConfig; private InterfaceSet mCurrentUpstreamIfaceSet; Loading Loading @@ -238,7 +241,6 @@ public class Tethering extends BaseNetworkObserver { stopTethering(downstream); }); mEntitlementMgr.setTetheringConfigurationFetcher(() -> { maybeDefaultDataSubChanged(); return mConfig; }); Loading @@ -250,14 +252,16 @@ public class Tethering extends BaseNetworkObserver { mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); }); filter = new IntentFilter(); filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED); mDefaultSubscriptionChange = new VersionedBroadcastListener( "DefaultSubscriptionChangeListener", mContext, mHandler, filter, (Intent ignored) -> { mLog.log("OBSERVED default data subscription change"); maybeDefaultDataSubChanged(); // To avoid launch unexpected provisioning checks, ignore re-provisioning when mPhoneStateListener = new PhoneStateListener(mLooper) { @Override public void onActiveDataSubscriptionIdChanged(int subId) { mLog.log("OBSERVED active data subscription change, from " + mActiveDataSubId + " to " + subId); if (subId == mActiveDataSubId) return; mActiveDataSubId = subId; updateConfiguration(); // To avoid launching unexpected provisioning checks, ignore re-provisioning when // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be // triggered again when CarrierConfig is loaded. if (mEntitlementMgr.getCarrierConfig(mConfig) != null) { Loading @@ -265,7 +269,9 @@ public class Tethering extends BaseNetworkObserver { } else { mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded"); } }); } }; mStateReceiver = new StateReceiver(); // Load tethering configuration. Loading @@ -276,7 +282,8 @@ public class Tethering extends BaseNetworkObserver { private void startStateMachineUpdaters(Handler handler) { mCarrierConfigChange.startListening(); mDefaultSubscriptionChange.startListening(); TelephonyManager.from(mContext).listen(mPhoneStateListener, PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_STATE); Loading Loading @@ -304,27 +311,17 @@ public class Tethering extends BaseNetworkObserver { // NOTE: This is always invoked on the mLooper thread. private void updateConfiguration() { final int subId = mDeps.getDefaultDataSubscriptionId(); updateConfiguration(subId); } private void updateConfiguration(final int subId) { mConfig = new TetheringConfiguration(mContext, mLog, subId); mConfig = mDeps.generateTetheringConfiguration(mContext, mLog, mActiveDataSubId); mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); } private void maybeDunSettingChanged() { final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext); final boolean isDunRequired = TetheringConfiguration.checkDunRequired( mContext, mActiveDataSubId); if (isDunRequired == mConfig.isDunRequired) return; updateConfiguration(); } private void maybeDefaultDataSubChanged() { final int subId = mDeps.getDefaultDataSubscriptionId(); if (subId == mConfig.subId) return; updateConfiguration(subId); } @Override public void interfaceStatusChanged(String iface, boolean up) { // Never called directly: only called from interfaceLinkStateChanged. Loading
services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java +3 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,7 @@ public class TetheringConfiguration { tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs); tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs); isDunRequired = checkDunRequired(ctx); isDunRequired = checkDunRequired(ctx, subId); chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic); preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, isDunRequired); Loading Loading @@ -228,9 +228,9 @@ public class TetheringConfiguration { } /** Check whether dun is required. */ public static boolean checkDunRequired(Context ctx) { public static boolean checkDunRequired(Context ctx, int id) { final TelephonyManager tm = (TelephonyManager) ctx.getSystemService(TELEPHONY_SERVICE); return (tm != null) ? tm.getTetherApnRequired() : false; return (tm != null) ? tm.getTetherApnRequired(id) : false; } private static Collection<Integer> getUpstreamIfaceTypes(Resources res, boolean dunRequired) { Loading
services/core/java/com/android/server/connectivity/tethering/TetheringDependencies.java +4 −4 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ import android.net.NetworkRequest; import android.net.ip.IpServer; import android.net.util.SharedLog; import android.os.Handler; import android.telephony.SubscriptionManager; import com.android.internal.util.StateMachine; import com.android.server.connectivity.MockableSystemProperties; Loading Loading @@ -88,9 +87,10 @@ public class TetheringDependencies { } /** * Get default data subscription id to build TetheringConfiguration. * Generate a new TetheringConfiguration according to input sub Id. */ public int getDefaultDataSubscriptionId() { return SubscriptionManager.getDefaultDataSubscriptionId(); public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, int subId) { return new TetheringConfiguration(ctx, log, subId); } }
tests/net/java/com/android/server/connectivity/TetheringTest.java +37 −2 Original line number Diff line number Diff line Loading @@ -100,6 +100,8 @@ import android.os.UserManager; import android.os.test.TestLooper; import android.provider.Settings; import android.telephony.CarrierConfigManager; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.test.mock.MockContentResolver; import androidx.test.filters.SmallTest; Loading @@ -111,6 +113,7 @@ import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.connectivity.tethering.IPv6TetheringCoordinator; import com.android.server.connectivity.tethering.OffloadHardwareInterface; import com.android.server.connectivity.tethering.TetheringConfiguration; import com.android.server.connectivity.tethering.TetheringDependencies; import com.android.server.connectivity.tethering.UpstreamNetworkMonitor; Loading @@ -118,6 +121,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; Loading Loading @@ -147,6 +151,7 @@ public class TetheringTest { @Mock private MockableSystemProperties mSystemProperties; @Mock private OffloadHardwareInterface mOffloadHardwareInterface; @Mock private Resources mResources; @Mock private TelephonyManager mTelephonyManager; @Mock private UsbManager mUsbManager; @Mock private WifiManager mWifiManager; @Mock private CarrierConfigManager mCarrierConfigManager; Loading @@ -171,6 +176,7 @@ public class TetheringTest { private MockContentResolver mContentResolver; private BroadcastReceiver mBroadcastReceiver; private Tethering mTethering; private PhoneStateListener mPhoneStateListener; private class MockContext extends BroadcastInterceptingContext { MockContext(Context base) { Loading @@ -193,6 +199,7 @@ public class TetheringTest { public Object getSystemService(String name) { if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; if (Context.USB_SERVICE.equals(name)) return mUsbManager; if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; return super.getSystemService(name); } } Loading Loading @@ -234,6 +241,17 @@ public class TetheringTest { } } private class MockTetheringConfiguration extends TetheringConfiguration { MockTetheringConfiguration(Context ctx, SharedLog log, int id) { super(ctx, log, id); } @Override protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) { return mResources; } } public class MockTetheringDependencies extends TetheringDependencies { StateMachine upstreamNetworkMonitorMasterSM; ArrayList<IpServer> ipv6CoordinatorNotifyList; Loading Loading @@ -276,8 +294,9 @@ public class TetheringTest { } @Override public int getDefaultDataSubscriptionId() { return INVALID_SUBSCRIPTION_ID; public TetheringConfiguration generateTetheringConfiguration(Context ctx, SharedLog log, int subId) { return new MockTetheringConfiguration(ctx, log, subId); } } Loading Loading @@ -372,6 +391,11 @@ public class TetheringTest { mTetheringDependencies.reset(); mTethering = makeTethering(); verify(mNMService).registerTetheringStatsProvider(any(), anyString()); final ArgumentCaptor<PhoneStateListener> phoneListenerCaptor = ArgumentCaptor.forClass(PhoneStateListener.class); verify(mTelephonyManager).listen(phoneListenerCaptor.capture(), eq(PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)); mPhoneStateListener = phoneListenerCaptor.getValue(); } private Tethering makeTethering() { Loading Loading @@ -982,6 +1006,17 @@ public class TetheringTest { callback2.expectUpstreamChanged(upstreamState.network); } @Test public void testMultiSimAware() throws Exception { final TetheringConfiguration initailConfig = mTethering.getTetheringConfiguration(); assertEquals(INVALID_SUBSCRIPTION_ID, initailConfig.subId); final int fakeSubId = 1234; mPhoneStateListener.onActiveDataSubscriptionIdChanged(fakeSubId); final TetheringConfiguration newConfig = mTethering.getTetheringConfiguration(); assertEquals(fakeSubId, newConfig.subId); } // TODO: Test that a request for hotspot mode doesn't interfere with an // already operating tethering mode interface. }
tests/net/java/com/android/server/connectivity/tethering/TetheringConfigurationTest.java +6 −5 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import static com.android.internal.R.array.config_tether_upstream_types; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.when; import android.content.ContentResolver; Loading Loading @@ -141,7 +142,7 @@ public class TetheringConfigurationTest { @Test public void testDunFromTelephonyManagerMeansDun() { when(mTelephonyManager.getTetherApnRequired()).thenReturn(true); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(true); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( Loading @@ -165,7 +166,7 @@ public class TetheringConfigurationTest { @Test public void testDunNotRequiredFromTelephonyManagerMeansNoDun() { when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfgWifi = getTetheringConfiguration(TYPE_WIFI); final TetheringConfiguration cfgMobileWifiHipri = getTetheringConfiguration( Loading Loading @@ -208,7 +209,7 @@ public class TetheringConfigurationTest { @Test public void testNoDefinedUpstreamTypesAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn(new int[]{}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading @@ -231,7 +232,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesSansEthernetAddsEthernet() { when(mResources.getIntArray(config_tether_upstream_types)).thenReturn( new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading @@ -249,7 +250,7 @@ public class TetheringConfigurationTest { public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() { when(mResources.getIntArray(config_tether_upstream_types)) .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI}); when(mTelephonyManager.getTetherApnRequired()).thenReturn(false); when(mTelephonyManager.getTetherApnRequired(anyInt())).thenReturn(false); final TetheringConfiguration cfg = new TetheringConfiguration( mMockContext, mLog, INVALID_SUBSCRIPTION_ID); Loading