Support multi-SIM entitlement check

1. Trigger entitlement recheck when perferred SIM switch.
2. Get resources from preferred SIM's subId to build
   TetheringConfiguration.

Bug: 120069528
Bug: 122108346
Test: -atest FrameworksNetTests
      -build, flash, booted
      -manual hotspot hotspot with DSDS switch

Change-Id: Icbfa8e84d675c95c0c5563087490ca8e36d91b73
This commit is contained in:
markchien
2019-01-08 23:52:21 +08:00
parent 8fc0510830
commit 293422f1d0
6 changed files with 155 additions and 38 deletions

View File

@@ -96,6 +96,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.MessageUtils; import com.android.internal.util.MessageUtils;
@@ -180,6 +181,7 @@ public class Tethering extends BaseNetworkObserver {
// into a single coherent structure. // into a single coherent structure.
private final HashSet<IpServer> mForwardedDownstreams; private final HashSet<IpServer> mForwardedDownstreams;
private final VersionedBroadcastListener mCarrierConfigChange; private final VersionedBroadcastListener mCarrierConfigChange;
private final VersionedBroadcastListener mDefaultSubscriptionChange;
private final TetheringDependencies mDeps; private final TetheringDependencies mDeps;
private final EntitlementManager mEntitlementMgr; private final EntitlementManager mEntitlementMgr;
@@ -232,6 +234,15 @@ public class Tethering extends BaseNetworkObserver {
mEntitlementMgr.reevaluateSimCardProvisioning(); mEntitlementMgr.reevaluateSimCardProvisioning();
}); });
filter = new IntentFilter();
filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
mDefaultSubscriptionChange = new VersionedBroadcastListener(
"DefaultSubscriptionChangeListener", mContext, smHandler, filter,
(Intent ignored) -> {
mLog.log("OBSERVED default data subscription change");
updateConfiguration();
mEntitlementMgr.reevaluateSimCardProvisioning();
});
mStateReceiver = new StateReceiver(); mStateReceiver = new StateReceiver();
// Load tethering configuration. // Load tethering configuration.
@@ -242,6 +253,7 @@ public class Tethering extends BaseNetworkObserver {
private void startStateMachineUpdaters() { private void startStateMachineUpdaters() {
mCarrierConfigChange.startListening(); mCarrierConfigChange.startListening();
mDefaultSubscriptionChange.startListening();
final Handler handler = mTetherMasterSM.getHandler(); final Handler handler = mTetherMasterSM.getHandler();
IntentFilter filter = new IntentFilter(); IntentFilter filter = new IntentFilter();
@@ -270,7 +282,8 @@ public class Tethering extends BaseNetworkObserver {
// NOTE: This is always invoked on the mLooper thread. // NOTE: This is always invoked on the mLooper thread.
private void updateConfiguration() { private void updateConfiguration() {
mConfig = new TetheringConfiguration(mContext, mLog); final int subId = mDeps.getDefaultDataSubscriptionId();
mConfig = new TetheringConfiguration(mContext, mLog, subId);
mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired);
mEntitlementMgr.updateConfiguration(mConfig); mEntitlementMgr.updateConfiguration(mConfig);
} }

View File

@@ -26,8 +26,8 @@ import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
import static com.android.internal.R.array.config_mobile_hotspot_provision_app; import static com.android.internal.R.array.config_mobile_hotspot_provision_app;
import static com.android.internal.R.array.config_tether_bluetooth_regexs; import static com.android.internal.R.array.config_tether_bluetooth_regexs;
import static com.android.internal.R.array.config_tether_dhcp_range; import static com.android.internal.R.array.config_tether_dhcp_range;
import static com.android.internal.R.array.config_tether_usb_regexs;
import static com.android.internal.R.array.config_tether_upstream_types; import static com.android.internal.R.array.config_tether_upstream_types;
import static com.android.internal.R.array.config_tether_usb_regexs;
import static com.android.internal.R.array.config_tether_wifi_regexs; import static com.android.internal.R.array.config_tether_wifi_regexs;
import static com.android.internal.R.bool.config_tether_upstream_automatic; import static com.android.internal.R.bool.config_tether_upstream_automatic;
import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui; import static com.android.internal.R.string.config_mobile_hotspot_provision_app_no_ui;
@@ -38,6 +38,7 @@ import android.content.res.Resources;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.util.SharedLog; import android.net.util.SharedLog;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
@@ -100,29 +101,34 @@ public class TetheringConfiguration {
public final String[] provisioningApp; public final String[] provisioningApp;
public final String provisioningAppNoUi; public final String provisioningAppNoUi;
public TetheringConfiguration(Context ctx, SharedLog log) { public final int subId;
public TetheringConfiguration(Context ctx, SharedLog log, int id) {
final SharedLog configLog = log.forSubComponent("config"); final SharedLog configLog = log.forSubComponent("config");
tetherableUsbRegexs = getResourceStringArray(ctx, config_tether_usb_regexs); subId = id;
Resources res = getResources(ctx, subId);
tetherableUsbRegexs = getResourceStringArray(res, config_tether_usb_regexs);
// TODO: Evaluate deleting this altogether now that Wi-Fi always passes // TODO: Evaluate deleting this altogether now that Wi-Fi always passes
// us an interface name. Careful consideration needs to be given to // us an interface name. Careful consideration needs to be given to
// implications for Settings and for provisioning checks. // implications for Settings and for provisioning checks.
tetherableWifiRegexs = getResourceStringArray(ctx, config_tether_wifi_regexs); tetherableWifiRegexs = getResourceStringArray(res, config_tether_wifi_regexs);
tetherableBluetoothRegexs = getResourceStringArray(ctx, config_tether_bluetooth_regexs); tetherableBluetoothRegexs = getResourceStringArray(res, config_tether_bluetooth_regexs);
dunCheck = checkDunRequired(ctx); dunCheck = checkDunRequired(ctx);
configLog.log("DUN check returned: " + dunCheckString(dunCheck)); configLog.log("DUN check returned: " + dunCheckString(dunCheck));
chooseUpstreamAutomatically = getResourceBoolean(ctx, config_tether_upstream_automatic); chooseUpstreamAutomatically = getResourceBoolean(res, config_tether_upstream_automatic);
preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(ctx, dunCheck); preferredUpstreamIfaceTypes = getUpstreamIfaceTypes(res, dunCheck);
isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN); isDunRequired = preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN);
legacyDhcpRanges = getLegacyDhcpRanges(ctx); legacyDhcpRanges = getLegacyDhcpRanges(res);
defaultIPv4DNS = copy(DEFAULT_IPV4_DNS); defaultIPv4DNS = copy(DEFAULT_IPV4_DNS);
enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx); enableLegacyDhcpServer = getEnableLegacyDhcpServer(ctx);
provisioningApp = getResourceStringArray(ctx, config_mobile_hotspot_provision_app); provisioningApp = getResourceStringArray(res, config_mobile_hotspot_provision_app);
provisioningAppNoUi = getProvisioningAppNoUi(ctx); provisioningAppNoUi = getProvisioningAppNoUi(res);
configLog.log(toString()); configLog.log(toString());
} }
@@ -144,6 +150,9 @@ public class TetheringConfiguration {
} }
public void dump(PrintWriter pw) { public void dump(PrintWriter pw) {
pw.print("subId: ");
pw.println(subId);
dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs); dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs); dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs); dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs);
@@ -169,6 +178,7 @@ public class TetheringConfiguration {
public String toString() { public String toString() {
final StringJoiner sj = new StringJoiner(" "); final StringJoiner sj = new StringJoiner(" ");
sj.add(String.format("subId:%d", subId));
sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs))); sj.add(String.format("tetherableUsbRegexs:%s", makeString(tetherableUsbRegexs)));
sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs))); sj.add(String.format("tetherableWifiRegexs:%s", makeString(tetherableWifiRegexs)));
sj.add(String.format("tetherableBluetoothRegexs:%s", sj.add(String.format("tetherableBluetoothRegexs:%s",
@@ -235,8 +245,8 @@ public class TetheringConfiguration {
} }
} }
private static Collection<Integer> getUpstreamIfaceTypes(Context ctx, int dunCheck) { private static Collection<Integer> getUpstreamIfaceTypes(Resources res, int dunCheck) {
final int ifaceTypes[] = ctx.getResources().getIntArray(config_tether_upstream_types); final int[] ifaceTypes = res.getIntArray(config_tether_upstream_types);
final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length); final ArrayList<Integer> upstreamIfaceTypes = new ArrayList<>(ifaceTypes.length);
for (int i : ifaceTypes) { for (int i : ifaceTypes) {
switch (i) { switch (i) {
@@ -286,33 +296,33 @@ public class TetheringConfiguration {
return false; return false;
} }
private static String[] getLegacyDhcpRanges(Context ctx) { private static String[] getLegacyDhcpRanges(Resources res) {
final String[] fromResource = getResourceStringArray(ctx, config_tether_dhcp_range); final String[] fromResource = getResourceStringArray(res, config_tether_dhcp_range);
if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) { if ((fromResource.length > 0) && (fromResource.length % 2 == 0)) {
return fromResource; return fromResource;
} }
return copy(LEGACY_DHCP_DEFAULT_RANGE); return copy(LEGACY_DHCP_DEFAULT_RANGE);
} }
private static String getProvisioningAppNoUi(Context ctx) { private static String getProvisioningAppNoUi(Resources res) {
try { try {
return ctx.getResources().getString(config_mobile_hotspot_provision_app_no_ui); return res.getString(config_mobile_hotspot_provision_app_no_ui);
} catch (Resources.NotFoundException e) { } catch (Resources.NotFoundException e) {
return ""; return "";
} }
} }
private static boolean getResourceBoolean(Context ctx, int resId) { private static boolean getResourceBoolean(Resources res, int resId) {
try { try {
return ctx.getResources().getBoolean(resId); return res.getBoolean(resId);
} catch (Resources.NotFoundException e404) { } catch (Resources.NotFoundException e404) {
return false; return false;
} }
} }
private static String[] getResourceStringArray(Context ctx, int resId) { private static String[] getResourceStringArray(Resources res, int resId) {
try { try {
final String[] strArray = ctx.getResources().getStringArray(resId); final String[] strArray = res.getStringArray(resId);
return (strArray != null) ? strArray : EMPTY_STRING_ARRAY; return (strArray != null) ? strArray : EMPTY_STRING_ARRAY;
} catch (Resources.NotFoundException e404) { } catch (Resources.NotFoundException e404) {
return EMPTY_STRING_ARRAY; return EMPTY_STRING_ARRAY;
@@ -325,6 +335,19 @@ public class TetheringConfiguration {
return intVal != 0; return intVal != 0;
} }
private Resources getResources(Context ctx, int subId) {
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return getResourcesForSubIdWrapper(ctx, subId);
} else {
return ctx.getResources();
}
}
@VisibleForTesting
protected Resources getResourcesForSubIdWrapper(Context ctx, int subId) {
return SubscriptionManager.getResourcesForSubId(ctx, subId);
}
private static String[] copy(String[] strarray) { private static String[] copy(String[] strarray) {
return Arrays.copyOf(strarray, strarray.length); return Arrays.copyOf(strarray, strarray.length);
} }

View File

@@ -21,6 +21,7 @@ import android.net.NetworkRequest;
import android.net.ip.IpServer; import android.net.ip.IpServer;
import android.net.util.SharedLog; import android.net.util.SharedLog;
import android.os.Handler; import android.os.Handler;
import android.telephony.SubscriptionManager;
import com.android.internal.util.StateMachine; import com.android.internal.util.StateMachine;
import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.MockableSystemProperties;
@@ -85,4 +86,11 @@ public class TetheringDependencies {
SharedLog log, MockableSystemProperties systemProperties) { SharedLog log, MockableSystemProperties systemProperties) {
return new EntitlementManager(ctx, target, log, systemProperties); return new EntitlementManager(ctx, target, log, systemProperties);
} }
/**
* Get default data subscription id to build TetheringConfiguration.
*/
public int getDefaultDataSubscriptionId() {
return SubscriptionManager.getDefaultDataSubscriptionId();
}
} }

View File

@@ -35,6 +35,7 @@ import static android.net.wifi.WifiManager.IFACE_IP_MODE_LOCAL_ONLY;
import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED; import static android.net.wifi.WifiManager.IFACE_IP_MODE_TETHERED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED; import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -274,6 +275,11 @@ public class TetheringTest {
isTetheringSupportedCalls++; isTetheringSupportedCalls++;
return true; return true;
} }
@Override
public int getDefaultDataSubscriptionId() {
return INVALID_SUBSCRIPTION_ID;
}
} }
private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6,

View File

@@ -21,6 +21,7 @@ import static android.net.ConnectivityManager.TETHERING_WIFI;
import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN; import static android.net.ConnectivityManager.TETHER_ERROR_ENTITLEMENT_UNKONWN;
import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR; import static android.net.ConnectivityManager.TETHER_ERROR_NO_ERROR;
import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
@@ -140,7 +141,8 @@ public final class EntitlementManagerTest {
mMockContext = new MockContext(mContext); mMockContext = new MockContext(mContext);
mSM = new TestStateMachine(); mSM = new TestStateMachine();
mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties); mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, mSystemProperties);
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
} }
@After @After
@@ -168,7 +170,8 @@ public final class EntitlementManagerTest {
@Test @Test
public void canRequireProvisioning() { public void canRequireProvisioning() {
setupForRequiredProvisioning(); setupForRequiredProvisioning();
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
assertTrue(mEnMgr.isTetherProvisioningRequired()); assertTrue(mEnMgr.isTetherProvisioningRequired());
} }
@@ -177,7 +180,8 @@ public final class EntitlementManagerTest {
setupForRequiredProvisioning(); setupForRequiredProvisioning();
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
.thenReturn(null); .thenReturn(null);
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
// Couldn't get the CarrierConfigManager, but still had a declared provisioning app. // Couldn't get the CarrierConfigManager, but still had a declared provisioning app.
// Therefore provisioning still be required. // Therefore provisioning still be required.
assertTrue(mEnMgr.isTetherProvisioningRequired()); assertTrue(mEnMgr.isTetherProvisioningRequired());
@@ -187,7 +191,8 @@ public final class EntitlementManagerTest {
public void toleratesCarrierConfigMissing() { public void toleratesCarrierConfigMissing() {
setupForRequiredProvisioning(); setupForRequiredProvisioning();
when(mCarrierConfigManager.getConfig()).thenReturn(null); when(mCarrierConfigManager.getConfig()).thenReturn(null);
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
// We still have a provisioning app configured, so still require provisioning. // We still have a provisioning app configured, so still require provisioning.
assertTrue(mEnMgr.isTetherProvisioningRequired()); assertTrue(mEnMgr.isTetherProvisioningRequired());
} }
@@ -197,11 +202,13 @@ public final class EntitlementManagerTest {
setupForRequiredProvisioning(); setupForRequiredProvisioning();
when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
.thenReturn(null); .thenReturn(null);
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
assertFalse(mEnMgr.isTetherProvisioningRequired()); assertFalse(mEnMgr.isTetherProvisioningRequired());
when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app))
.thenReturn(new String[] {"malformedApp"}); .thenReturn(new String[] {"malformedApp"});
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(
new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID));
assertFalse(mEnMgr.isTetherProvisioningRequired()); assertFalse(mEnMgr.isTetherProvisioningRequired());
} }
@@ -223,7 +230,8 @@ public final class EntitlementManagerTest {
assertFalse(mEnMgr.everRunUiEntitlement); assertFalse(mEnMgr.everRunUiEntitlement);
setupForRequiredProvisioning(); setupForRequiredProvisioning();
mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog)); mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog,
INVALID_SUBSCRIPTION_ID));
// 2. No cache value and don't need to run entitlement check. // 2. No cache value and don't need to run entitlement check.
mEnMgr.everRunUiEntitlement = false; mEnMgr.everRunUiEntitlement = false;
receiver = new ResultReceiver(null) { receiver = new ResultReceiver(null) {

View File

@@ -22,10 +22,12 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI; import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER; import static android.provider.Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_NOT_REQUIRED;
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_REQUIRED;
import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED; import static com.android.server.connectivity.tethering.TetheringConfiguration.DUN_UNSPECIFIED;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@@ -44,26 +46,39 @@ import android.test.mock.MockContentResolver;
import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.internal.util.test.FakeSettingsProvider; import com.android.internal.util.test.FakeSettingsProvider;
import java.util.Iterator;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
import java.util.Iterator;
@RunWith(AndroidJUnit4.class) @RunWith(AndroidJUnit4.class)
@SmallTest @SmallTest
public class TetheringConfigurationTest { public class TetheringConfigurationTest {
private final SharedLog mLog = new SharedLog("TetheringConfigurationTest"); private final SharedLog mLog = new SharedLog("TetheringConfigurationTest");
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
@Mock private Context mContext; @Mock private Context mContext;
@Mock private TelephonyManager mTelephonyManager; @Mock private TelephonyManager mTelephonyManager;
@Mock private Resources mResources; @Mock private Resources mResources;
@Mock private Resources mResourcesForSubId;
private MockContentResolver mContentResolver; private MockContentResolver mContentResolver;
private Context mMockContext; private Context mMockContext;
private boolean mHasTelephonyManager; private boolean mHasTelephonyManager;
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 mResourcesForSubId;
}
}
private class MockContext extends BroadcastInterceptingContext { private class MockContext extends BroadcastInterceptingContext {
MockContext(Context base) { MockContext(Context base) {
super(base); super(base);
@@ -99,6 +114,9 @@ public class TetheringConfigurationTest {
.thenReturn(new String[0]); .thenReturn(new String[0]);
when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types)) when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
.thenReturn(new int[0]); .thenReturn(new int[0]);
when(mResources.getStringArray(
com.android.internal.R.array.config_mobile_hotspot_provision_app))
.thenReturn(new String[0]);
mContentResolver = new MockContentResolver(); mContentResolver = new MockContentResolver();
mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
mMockContext = new MockContext(mContext); mMockContext = new MockContext(mContext);
@@ -111,7 +129,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = true; mHasTelephonyManager = true;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_REQUIRED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertTrue(cfg.isDunRequired); assertTrue(cfg.isDunRequired);
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
@@ -127,7 +146,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = true; mHasTelephonyManager = true;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_NOT_REQUIRED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertFalse(cfg.isDunRequired); assertFalse(cfg.isDunRequired);
assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE)); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
@@ -143,7 +163,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = false; mHasTelephonyManager = false;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertTrue(cfg.isDunRequired); assertTrue(cfg.isDunRequired);
assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN)); assertTrue(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_DUN));
// Just to prove we haven't clobbered Wi-Fi: // Just to prove we haven't clobbered Wi-Fi:
@@ -160,7 +181,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = false; mHasTelephonyManager = false;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext()); assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -181,7 +203,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = false; mHasTelephonyManager = false;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext()); assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue()); assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
@@ -199,7 +222,8 @@ public class TetheringConfigurationTest {
mHasTelephonyManager = false; mHasTelephonyManager = false;
when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED); when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator(); final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
assertTrue(upstreamIterator.hasNext()); assertTrue(upstreamIterator.hasNext());
assertEquals(TYPE_WIFI, upstreamIterator.next().intValue()); assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
@@ -214,7 +238,8 @@ public class TetheringConfigurationTest {
public void testNewDhcpServerDisabled() { public void testNewDhcpServerDisabled() {
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1); Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 1);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertTrue(cfg.enableLegacyDhcpServer); assertTrue(cfg.enableLegacyDhcpServer);
} }
@@ -222,7 +247,41 @@ public class TetheringConfigurationTest {
public void testNewDhcpServerEnabled() { public void testNewDhcpServerEnabled() {
Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0); Settings.Global.putInt(mContentResolver, TETHER_ENABLE_LEGACY_DHCP_SERVER, 0);
final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog); final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertFalse(cfg.enableLegacyDhcpServer); assertFalse(cfg.enableLegacyDhcpServer);
} }
@Test
public void testGetResourcesBySubId() {
setUpResourceForSubId();
final TetheringConfiguration cfg = new TetheringConfiguration(
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
assertTrue(cfg.provisioningApp.length == 0);
final int anyValidSubId = 1;
final MockTetheringConfiguration mockCfg =
new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId);
assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]);
assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]);
}
private void setUpResourceForSubId() {
when(mResourcesForSubId.getStringArray(
com.android.internal.R.array.config_tether_dhcp_range)).thenReturn(new String[0]);
when(mResourcesForSubId.getStringArray(
com.android.internal.R.array.config_tether_usb_regexs)).thenReturn(new String[0]);
when(mResourcesForSubId.getStringArray(
com.android.internal.R.array.config_tether_wifi_regexs))
.thenReturn(new String[]{ "test_wlan\\d" });
when(mResourcesForSubId.getStringArray(
com.android.internal.R.array.config_tether_bluetooth_regexs))
.thenReturn(new String[0]);
when(mResourcesForSubId.getIntArray(
com.android.internal.R.array.config_tether_upstream_types))
.thenReturn(new int[0]);
when(mResourcesForSubId.getStringArray(
com.android.internal.R.array.config_mobile_hotspot_provision_app))
.thenReturn(PROVISIONING_APP_NAME);
}
} }