From 3394e14fc3f5ce76162a9c2982831f200b80ee61 Mon Sep 17 00:00:00 2001 From: markchien Date: Tue, 9 Apr 2019 15:53:24 +0800 Subject: [PATCH] Tethering: fix using wrong subId problem There is the potential bug[1] that default data subId change intent may lose. So tethering may cache the outdated default data subId in TetheringConfiguration. Now EntitlementManager would fetch configuration every time and this would re-exam whether subId is changed. Additional passing subId to Settings to avoid default data subId change right away when launching entitlement check. Thus, Settings can know whether this is outdated entitlement check request. [1] b/129224596 Bug: 129751453 Test: -build, flash, boot -atest FrameworksNetTests -manual test with carrier SIM Change-Id: If334dd1cd383cced9db5cf0d0bc9dc60ed198816 --- .../server/connectivity/Tethering.java | 31 +++-- .../tethering/EntitlementManager.java | 126 ++++++++++-------- .../tethering/EntitlementManagerTest.java | 58 +++----- 3 files changed, 117 insertions(+), 98 deletions(-) diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index b140c1b25320f..33c84d161a90c 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -237,13 +237,17 @@ public class Tethering extends BaseNetworkObserver { mLog.log("OBSERVED UiEnitlementFailed"); stopTethering(downstream); }); + mEntitlementMgr.setTetheringConfigurationFetcher(() -> { + maybeDefaultDataSubChanged(); + return mConfig; + }); mCarrierConfigChange = new VersionedBroadcastListener( "CarrierConfigChangeListener", mContext, mHandler, filter, (Intent ignored) -> { mLog.log("OBSERVED carrier config change"); updateConfiguration(); - mEntitlementMgr.reevaluateSimCardProvisioning(); + mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); }); filter = new IntentFilter(); @@ -252,12 +256,12 @@ public class Tethering extends BaseNetworkObserver { "DefaultSubscriptionChangeListener", mContext, mHandler, filter, (Intent ignored) -> { mLog.log("OBSERVED default data subscription change"); - updateConfiguration(); + maybeDefaultDataSubChanged(); // To avoid launch unexpected provisioning checks, ignore re-provisioning when // no CarrierConfig loaded yet. Assume reevaluateSimCardProvisioning() will be // triggered again when CarrierConfig is loaded. - if (mEntitlementMgr.getCarrierConfig() != null) { - mEntitlementMgr.reevaluateSimCardProvisioning(); + if (mEntitlementMgr.getCarrierConfig(mConfig) != null) { + mEntitlementMgr.reevaluateSimCardProvisioning(mConfig); } else { mLog.log("IGNORED reevaluate provisioning due to no carrier config loaded"); } @@ -301,17 +305,26 @@ public class Tethering extends BaseNetworkObserver { // NOTE: This is always invoked on the mLooper thread. private void updateConfiguration() { final int subId = mDeps.getDefaultDataSubscriptionId(); - mConfig = new TetheringConfiguration(mContext, mLog, subId); - mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); - mEntitlementMgr.updateConfiguration(mConfig); + updateConfiguration(subId); } - private void maybeUpdateConfiguration() { + private void updateConfiguration(final int subId) { + mConfig = new TetheringConfiguration(mContext, mLog, subId); + mUpstreamNetworkMonitor.updateMobileRequiresDun(mConfig.isDunRequired); + } + + private void maybeDunSettingChanged() { final boolean isDunRequired = TetheringConfiguration.checkDunRequired(mContext); 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. @@ -1183,7 +1196,7 @@ public class Tethering extends BaseNetworkObserver { protected void chooseUpstreamType(boolean tryCell) { // We rebuild configuration on ACTION_CONFIGURATION_CHANGED, but we // do not currently know how to watch for changes in DUN settings. - maybeUpdateConfiguration(); + maybeDunSettingChanged(); final TetheringConfiguration config = mConfig; final NetworkState ns = (config.chooseUpstreamAutomatically) diff --git a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java index b0bbd72794d95..836f1e64aa9ce 100644 --- a/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java +++ b/services/core/java/com/android/server/connectivity/tethering/EntitlementManager.java @@ -29,7 +29,6 @@ import static android.net.ConnectivityManager.TETHER_ERROR_PROVISION_FAILED; import static com.android.internal.R.string.config_wifi_tether_enable; -import android.annotation.Nullable; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -76,6 +75,7 @@ public class EntitlementManager { protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning"; private static final String ACTION_PROVISIONING_ALARM = "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM"; + private static final String EXTRA_SUBID = "subId"; // {@link ComponentName} of the Service used to run tether provisioning. private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString( @@ -99,7 +99,6 @@ public class EntitlementManager { private final SharedLog mLog; private final SparseIntArray mEntitlementCacheValue; private final EntitlementHandler mHandler; - private @Nullable TetheringConfiguration mConfig; private final StateMachine mTetherMasterSM; // Key: ConnectivityManager.TETHERING_*(downstream). // Value: ConnectivityManager.TETHER_ERROR_{NO_ERROR or PROVISION_FAILED}(provisioning result). @@ -109,6 +108,7 @@ public class EntitlementManager { private boolean mUsingCellularAsUpstream = false; private boolean mNeedReRunProvisioningUi = false; private OnUiEntitlementFailedListener mListener; + private TetheringConfigurationFetcher mFetcher; public EntitlementManager(Context ctx, StateMachine tetherMasterSM, SharedLog log, int permissionChangeMessageCode, MockableSystemProperties systemProperties) { @@ -143,12 +143,18 @@ public class EntitlementManager { void onUiEntitlementFailed(int downstream); } - /** - * Pass a new TetheringConfiguration instance each time when - * Tethering#updateConfiguration() is called. - */ - public void updateConfiguration(TetheringConfiguration conf) { - mConfig = conf; + public void setTetheringConfigurationFetcher(final TetheringConfigurationFetcher fetcher) { + mFetcher = fetcher; + } + + /** Interface to fetch TetheringConfiguration. */ + public interface TetheringConfigurationFetcher { + /** + * Fetch current tethering configuration. This will be called to ensure whether entitlement + * check is needed. + * @return TetheringConfiguration instance. + */ + TetheringConfiguration fetchTetheringConfiguration(); } /** @@ -176,7 +182,8 @@ public class EntitlementManager { if (!mCurrentTethers.contains(type)) mCurrentTethers.add(type); - if (isTetherProvisioningRequired()) { + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + if (isTetherProvisioningRequired(config)) { // If provisioning is required and the result is not available yet, // cellular upstream should not be allowed. if (mCellularPermitted.size() == 0) { @@ -186,9 +193,9 @@ public class EntitlementManager { // till upstream change to cellular. if (mUsingCellularAsUpstream) { if (showProvisioningUi) { - runUiTetherProvisioning(type); + runUiTetherProvisioning(type, config.subId); } else { - runSilentTetherProvisioning(type); + runSilentTetherProvisioning(type, config.subId); } mNeedReRunProvisioningUi = false; } else { @@ -237,7 +244,8 @@ public class EntitlementManager { mUsingCellularAsUpstream = isCellular; if (mUsingCellularAsUpstream) { - handleMaybeRunProvisioning(); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + handleMaybeRunProvisioning(config); } } @@ -246,8 +254,8 @@ public class EntitlementManager { mHandler.sendMessage(mHandler.obtainMessage(EVENT_MAYBE_RUN_PROVISIONING)); } - private void handleMaybeRunProvisioning() { - if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired()) { + private void handleMaybeRunProvisioning(final TetheringConfiguration config) { + if (mCurrentTethers.size() == 0 || !isTetherProvisioningRequired(config)) { return; } @@ -259,9 +267,9 @@ public class EntitlementManager { if (mCellularPermitted.indexOfKey(downstream) < 0) { if (mNeedReRunProvisioningUi) { mNeedReRunProvisioningUi = false; - runUiTetherProvisioning(downstream); + runUiTetherProvisioning(downstream, config.subId); } else { - runSilentTetherProvisioning(downstream); + runSilentTetherProvisioning(downstream, config.subId); } } } @@ -270,29 +278,31 @@ public class EntitlementManager { /** * Check if the device requires a provisioning check in order to enable tethering. * + * @param config an object that encapsulates the various tethering configuration elements. * @return a boolean - {@code true} indicating tether provisioning is required by the carrier. */ @VisibleForTesting - public boolean isTetherProvisioningRequired() { + protected boolean isTetherProvisioningRequired(final TetheringConfiguration config) { if (mSystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false) - || mConfig.provisioningApp.length == 0) { + || config.provisioningApp.length == 0) { return false; } - if (carrierConfigAffirmsEntitlementCheckNotRequired()) { + if (carrierConfigAffirmsEntitlementCheckNotRequired(config)) { return false; } - return (mConfig.provisioningApp.length == 2); + return (config.provisioningApp.length == 2); } /** * Re-check tethering provisioning for all enabled tether types. * Reference ConnectivityManager.TETHERING_{@code *} for each tether type. * + * @param config an object that encapsulates the various tethering configuration elements. * Note: this method is only called from TetherMaster on the handler thread. * If there are new callers from different threads, the logic should move to * masterHandler to avoid race conditions. */ - public void reevaluateSimCardProvisioning() { + public void reevaluateSimCardProvisioning(final TetheringConfiguration config) { if (DBG) mLog.i("reevaluateSimCardProvisioning"); if (!mHandler.getLooper().isCurrentThread()) { @@ -303,24 +313,27 @@ public class EntitlementManager { mCellularPermitted.clear(); // TODO: refine provisioning check to isTetherProvisioningRequired() ?? - if (!mConfig.hasMobileHotspotProvisionApp() - || carrierConfigAffirmsEntitlementCheckNotRequired()) { - evaluateCellularPermission(); + if (!config.hasMobileHotspotProvisionApp() + || carrierConfigAffirmsEntitlementCheckNotRequired(config)) { + evaluateCellularPermission(config); return; } if (mUsingCellularAsUpstream) { - handleMaybeRunProvisioning(); + handleMaybeRunProvisioning(config); } } - /** Get carrier configuration bundle. */ - public PersistableBundle getCarrierConfig() { + /** + * Get carrier configuration bundle. + * @param config an object that encapsulates the various tethering configuration elements. + * */ + public PersistableBundle getCarrierConfig(final TetheringConfiguration config) { final CarrierConfigManager configManager = (CarrierConfigManager) mContext .getSystemService(Context.CARRIER_CONFIG_SERVICE); if (configManager == null) return null; - final PersistableBundle carrierConfig = configManager.getConfig(); + final PersistableBundle carrierConfig = configManager.getConfigForSubId(config.subId); if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) { return carrierConfig; @@ -334,9 +347,10 @@ public class EntitlementManager { // // TODO: find a better way to express this, or alter the checking process // entirely so that this is more intuitive. - private boolean carrierConfigAffirmsEntitlementCheckNotRequired() { + private boolean carrierConfigAffirmsEntitlementCheckNotRequired( + final TetheringConfiguration config) { // Check carrier config for entitlement checks - final PersistableBundle carrierConfig = getCarrierConfig(); + final PersistableBundle carrierConfig = getCarrierConfig(config); if (carrierConfig == null) return false; // A CarrierConfigManager was found and it has a config. @@ -348,17 +362,19 @@ public class EntitlementManager { /** * Run no UI tethering provisioning check. * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param subId default data subscription ID. */ - protected void runSilentTetherProvisioning(int type) { + @VisibleForTesting + protected void runSilentTetherProvisioning(int type, int subId) { if (DBG) mLog.i("runSilentTetherProvisioning: " + type); // For silent provisioning, settings would stop tethering when entitlement fail. - ResultReceiver receiver = buildProxyReceiver(type, - false/* notifyFail */, null); + ResultReceiver receiver = buildProxyReceiver(type, false/* notifyFail */, null); Intent intent = new Intent(); intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); intent.putExtra(EXTRA_RUN_PROVISION, true); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); + intent.putExtra(EXTRA_SUBID, subId); intent.setComponent(TETHER_SERVICE); final long ident = Binder.clearCallingIdentity(); try { @@ -368,24 +384,25 @@ public class EntitlementManager { } } + private void runUiTetherProvisioning(int type, int subId) { + ResultReceiver receiver = buildProxyReceiver(type, true/* notifyFail */, null); + runUiTetherProvisioning(type, subId, receiver); + } + /** * Run the UI-enabled tethering provisioning check. * @param type tethering type from ConnectivityManager.TETHERING_{@code *} + * @param subId default data subscription ID. + * @param receiver to receive entitlement check result. */ @VisibleForTesting - protected void runUiTetherProvisioning(int type) { - ResultReceiver receiver = buildProxyReceiver(type, - true/* notifyFail */, null); - runUiTetherProvisioning(type, receiver); - } - - @VisibleForTesting - protected void runUiTetherProvisioning(int type, ResultReceiver receiver) { + protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) { if (DBG) mLog.i("runUiTetherProvisioning: " + type); Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING); intent.putExtra(EXTRA_ADD_TETHER_TYPE, type); intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver); + intent.putExtra(EXTRA_SUBID, subId); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final long ident = Binder.clearCallingIdentity(); try { @@ -396,9 +413,9 @@ public class EntitlementManager { } // Not needed to check if this don't run on the handler thread because it's private. - private void scheduleProvisioningRechecks() { + private void scheduleProvisioningRechecks(final TetheringConfiguration config) { if (mProvisioningRecheckAlarm == null) { - final int period = mConfig.provisioningCheckPeriod; + final int period = config.provisioningCheckPeriod; if (period <= 0) return; Intent intent = new Intent(ACTION_PROVISIONING_ALARM); @@ -421,9 +438,9 @@ public class EntitlementManager { } } - private void evaluateCellularPermission() { + private void evaluateCellularPermission(final TetheringConfiguration config) { final boolean oldPermitted = mCellularUpstreamPermitted; - mCellularUpstreamPermitted = (!isTetherProvisioningRequired() + mCellularUpstreamPermitted = (!isTetherProvisioningRequired(config) || mCellularPermitted.indexOfValue(TETHER_ERROR_NO_ERROR) > -1); if (DBG) { @@ -438,7 +455,7 @@ public class EntitlementManager { // Only schedule periodic re-check when tether is provisioned // and the result is ok. if (mCellularUpstreamPermitted && mCellularPermitted.size() > 0) { - scheduleProvisioningRechecks(); + scheduleProvisioningRechecks(config); } else { cancelTetherProvisioningRechecks(); } @@ -457,7 +474,8 @@ public class EntitlementManager { if (!mCurrentTethers.contains(type)) return; mCellularPermitted.put(type, resultCode); - evaluateCellularPermission(); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + evaluateCellularPermission(config); } /** @@ -467,7 +485,8 @@ public class EntitlementManager { protected void removeDownstreamMapping(int type) { mLog.i("removeDownstreamMapping: " + type); mCellularPermitted.delete(type); - evaluateCellularPermission(); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + evaluateCellularPermission(config); } private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -475,7 +494,8 @@ public class EntitlementManager { public void onReceive(Context context, Intent intent) { if (ACTION_PROVISIONING_ALARM.equals(intent.getAction())) { mLog.log("Received provisioning alarm"); - reevaluateSimCardProvisioning(); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + reevaluateSimCardProvisioning(config); } } }; @@ -498,7 +518,8 @@ public class EntitlementManager { handleNotifyUpstream(toBool(msg.arg1)); break; case EVENT_MAYBE_RUN_PROVISIONING: - handleMaybeRunProvisioning(); + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + handleMaybeRunProvisioning(config); break; case EVENT_GET_ENTITLEMENT_VALUE: handleGetLatestTetheringEntitlementValue(msg.arg1, (ResultReceiver) msg.obj, @@ -636,7 +657,8 @@ public class EntitlementManager { private void handleGetLatestTetheringEntitlementValue(int downstream, ResultReceiver receiver, boolean showEntitlementUi) { - if (!isTetherProvisioningRequired()) { + final TetheringConfiguration config = mFetcher.fetchTetheringConfiguration(); + if (!isTetherProvisioningRequired(config)) { receiver.send(TETHER_ERROR_NO_ERROR, null); return; } @@ -647,7 +669,7 @@ public class EntitlementManager { receiver.send(cacheValue, null); } else { ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver); - runUiTetherProvisioning(downstream, proxy); + runUiTetherProvisioning(downstream, config.subId, proxy); } } } diff --git a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java index d28ab708f051e..2b2e8a72ab040 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/EntitlementManagerTest.java @@ -29,6 +29,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; @@ -93,6 +94,7 @@ public final class EntitlementManagerTest { private TestStateMachine mSM; private WrappedEntitlementManager mEnMgr; + private TetheringConfiguration mConfig; private class MockContext extends BroadcastInterceptingContext { MockContext(Context base) { @@ -127,13 +129,13 @@ public final class EntitlementManagerTest { } @Override - protected void runUiTetherProvisioning(int type, ResultReceiver receiver) { + protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) { uiProvisionCount++; receiver.send(fakeEntitlementResult, null); } @Override - protected void runSilentTetherProvisioning(int type) { + protected void runSilentTetherProvisioning(int type, int subId) { silentProvisionCount++; addDownstreamMapping(type, fakeEntitlementResult); } @@ -162,8 +164,10 @@ public final class EntitlementManagerTest { mEnMgr = new WrappedEntitlementManager(mMockContext, mSM, mLog, EVENT_EM_UPDATE, mSystemProperties); mEnMgr.setOnUiEntitlementFailedListener(mEntitlementFailedListener); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + mEnMgr.setTetheringConfigurationFetcher(() -> { + return mConfig; + }); } @After @@ -186,17 +190,16 @@ public final class EntitlementManagerTest { // Act like the CarrierConfigManager is present and ready unless told otherwise. when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) .thenReturn(mCarrierConfigManager); - when(mCarrierConfigManager.getConfig()).thenReturn(mCarrierConfig); + when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); } @Test public void canRequireProvisioning() { setupForRequiredProvisioning(); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); - assertTrue(mEnMgr.isTetherProvisioningRequired()); + assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig)); } @Test @@ -204,31 +207,27 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE)) .thenReturn(null); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); // Couldn't get the CarrierConfigManager, but still had a declared provisioning app. // Therefore provisioning still be required. - assertTrue(mEnMgr.isTetherProvisioningRequired()); + assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig)); } @Test public void toleratesCarrierConfigMissing() { setupForRequiredProvisioning(); when(mCarrierConfigManager.getConfig()).thenReturn(null); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); // We still have a provisioning app configured, so still require provisioning. - assertTrue(mEnMgr.isTetherProvisioningRequired()); + assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig)); } @Test public void toleratesCarrierConfigNotLoaded() { setupForRequiredProvisioning(); mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); // We still have a provisioning app configured, so still require provisioning. - assertTrue(mEnMgr.isTetherProvisioningRequired()); + assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig)); } @Test @@ -236,14 +235,12 @@ public final class EntitlementManagerTest { setupForRequiredProvisioning(); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(null); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); - assertFalse(mEnMgr.isTetherProvisioningRequired()); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig)); when(mResources.getStringArray(R.array.config_mobile_hotspot_provision_app)) .thenReturn(new String[] {"malformedApp"}); - mEnMgr.updateConfiguration( - new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID)); - assertFalse(mEnMgr.isTetherProvisioningRequired()); + mConfig = new TetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID); + assertFalse(mEnMgr.isTetherProvisioningRequired(mConfig)); } @Test @@ -265,8 +262,6 @@ public final class EntitlementManagerTest { mEnMgr.reset(); setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); // 2. No cache value and don't need to run entitlement check. receiver = new ResultReceiver(null) { @Override @@ -361,8 +356,6 @@ public final class EntitlementManagerTest { public void verifyPermissionResult() { setupForRequiredProvisioning(); mEnMgr.notifyUpstream(true); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); mLooper.dispatchAll(); @@ -379,8 +372,6 @@ public final class EntitlementManagerTest { public void verifyPermissionIfAllNotApproved() { setupForRequiredProvisioning(); mEnMgr.notifyUpstream(true); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); mLooper.dispatchAll(); @@ -399,8 +390,6 @@ public final class EntitlementManagerTest { public void verifyPermissionIfAnyApproved() { setupForRequiredProvisioning(); mEnMgr.notifyUpstream(true); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true); mLooper.dispatchAll(); @@ -419,8 +408,6 @@ public final class EntitlementManagerTest { @Test public void testRunTetherProvisioning() { setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); // 1. start ui provisioning, upstream is mobile mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR; mEnMgr.notifyUpstream(true); @@ -458,7 +445,7 @@ public final class EntitlementManagerTest { // 5. tear down mobile, then switch SIM mEnMgr.notifyUpstream(false); mLooper.dispatchAll(); - mEnMgr.reevaluateSimCardProvisioning(); + mEnMgr.reevaluateSimCardProvisioning(mConfig); assertEquals(0, mEnMgr.uiProvisionCount); assertEquals(0, mEnMgr.silentProvisionCount); mEnMgr.reset(); @@ -474,8 +461,6 @@ public final class EntitlementManagerTest { @Test public void testCallStopTetheringWhenUiProvisioningFail() { setupForRequiredProvisioning(); - mEnMgr.updateConfiguration(new TetheringConfiguration(mMockContext, mLog, - INVALID_SUBSCRIPTION_ID)); verify(mEntitlementFailedListener, times(0)).onUiEntitlementFailed(TETHERING_WIFI); mEnMgr.fakeEntitlementResult = TETHER_ERROR_PROVISION_FAILED; mEnMgr.notifyUpstream(true); @@ -486,7 +471,6 @@ public final class EntitlementManagerTest { verify(mEntitlementFailedListener, times(1)).onUiEntitlementFailed(TETHERING_WIFI); } - public class TestStateMachine extends StateMachine { public final ArrayList messages = new ArrayList<>(); private final State