Merge "[Tetheirng] Refactor carrier config to EntitlementManager" am: 1135676150
Original change: https://android-review.googlesource.com/c/platform/packages/modules/Connectivity/+/2033668 Change-Id: Ic9aca26e0b4dafedd3d9134ad80ec19fc887ad1e Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -34,7 +34,6 @@ import static android.net.TetheringManager.TETHER_ERROR_NO_ERROR;
|
||||
import static android.net.TetheringManager.TETHER_ERROR_PROVISIONING_FAILED;
|
||||
|
||||
import static com.android.networkstack.apishim.ConstantsShim.ACTION_TETHER_UNSUPPORTED_CARRIER_UI;
|
||||
import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
@@ -48,12 +47,10 @@ import android.net.util.SharedLog;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Parcel;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -307,13 +304,13 @@ public class EntitlementManager {
|
||||
if (SystemProperties.getBoolean(DISABLE_PROVISIONING_SYSPROP_KEY, false)) {
|
||||
return TETHERING_PROVISIONING_NOT_REQUIRED;
|
||||
}
|
||||
// TODO: Find a way to avoid get carrier config twice.
|
||||
if (carrierConfigAffirmsCarrierNotSupport(config)) {
|
||||
|
||||
if (!config.isCarrierSupportTethering) {
|
||||
// To block tethering, behave as if running provisioning check and failed.
|
||||
return TETHERING_PROVISIONING_CARRIER_UNSUPPORT;
|
||||
}
|
||||
|
||||
if (carrierConfigAffirmsEntitlementCheckNotRequired(config)) {
|
||||
if (!config.isCarrierConfigAffirmsEntitlementCheckRequired) {
|
||||
return TETHERING_PROVISIONING_NOT_REQUIRED;
|
||||
}
|
||||
return (config.provisioningApp.length == 2)
|
||||
@@ -379,57 +376,6 @@ public class EntitlementManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get carrier configuration bundle.
|
||||
* @param config an object that encapsulates the various tethering configuration elements.
|
||||
* */
|
||||
public PersistableBundle getCarrierConfig(final TetheringConfiguration config) {
|
||||
final CarrierConfigManager configManager = mContext
|
||||
.getSystemService(CarrierConfigManager.class);
|
||||
if (configManager == null) return null;
|
||||
|
||||
final PersistableBundle carrierConfig = configManager.getConfigForSubId(
|
||||
config.activeDataSubId);
|
||||
|
||||
if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
|
||||
return carrierConfig;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// The logic here is aimed solely at confirming that a CarrierConfig exists
|
||||
// and affirms that entitlement checks are not required.
|
||||
//
|
||||
// TODO: find a better way to express this, or alter the checking process
|
||||
// entirely so that this is more intuitive.
|
||||
// TODO: Find a way to avoid using getCarrierConfig everytime.
|
||||
private boolean carrierConfigAffirmsEntitlementCheckNotRequired(
|
||||
final TetheringConfiguration config) {
|
||||
// Check carrier config for entitlement checks
|
||||
final PersistableBundle carrierConfig = getCarrierConfig(config);
|
||||
if (carrierConfig == null) return false;
|
||||
|
||||
// A CarrierConfigManager was found and it has a config.
|
||||
final boolean isEntitlementCheckRequired = carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL);
|
||||
return !isEntitlementCheckRequired;
|
||||
}
|
||||
|
||||
private boolean carrierConfigAffirmsCarrierNotSupport(final TetheringConfiguration config) {
|
||||
if (!SdkLevel.isAtLeastT()) {
|
||||
return false;
|
||||
}
|
||||
// Check carrier config for entitlement checks
|
||||
final PersistableBundle carrierConfig = getCarrierConfig(config);
|
||||
if (carrierConfig == null) return false;
|
||||
|
||||
// A CarrierConfigManager was found and it has a config.
|
||||
final boolean mIsCarrierSupport = carrierConfig.getBoolean(
|
||||
KEY_CARRIER_SUPPORTS_TETHERING_BOOL, true);
|
||||
return !mIsCarrierSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run no UI tethering provisioning check.
|
||||
* @param type tethering type from TetheringManager.TETHERING_{@code *}
|
||||
@@ -479,7 +425,7 @@ public class EntitlementManager {
|
||||
|
||||
private void runTetheringProvisioning(
|
||||
boolean showProvisioningUi, int downstreamType, final TetheringConfiguration config) {
|
||||
if (carrierConfigAffirmsCarrierNotSupport(config)) {
|
||||
if (!config.isCarrierSupportTethering) {
|
||||
mListener.onTetherProvisioningFailed(downstreamType, "Carrier does not support.");
|
||||
if (showProvisioningUi) {
|
||||
showCarrierUnsupportedDialog();
|
||||
@@ -497,7 +443,7 @@ public class EntitlementManager {
|
||||
}
|
||||
|
||||
private void showCarrierUnsupportedDialog() {
|
||||
// This is only used when carrierConfigAffirmsCarrierNotSupport() is true.
|
||||
// This is only used when TetheringConfiguration.isCarrierSupportTethering is false.
|
||||
if (!SdkLevel.isAtLeastT()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ public class Tethering {
|
||||
// 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) {
|
||||
if (TetheringConfiguration.getCarrierConfig(mContext, subId) != null) {
|
||||
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
|
||||
} else {
|
||||
mLog.log("IGNORED reevaluate provisioning, no carrier config loaded");
|
||||
|
||||
@@ -24,14 +24,17 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
|
||||
|
||||
import static com.android.net.module.util.DeviceConfigUtils.TETHERING_MODULE_NAME;
|
||||
import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.net.TetheringConfigurationParcel;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
@@ -142,6 +145,9 @@ public class TetheringConfiguration {
|
||||
public final int provisioningCheckPeriod;
|
||||
public final String provisioningResponse;
|
||||
|
||||
public final boolean isCarrierSupportTethering;
|
||||
public final boolean isCarrierConfigAffirmsEntitlementCheckRequired;
|
||||
|
||||
public final int activeDataSubId;
|
||||
|
||||
private final boolean mEnableLegacyDhcpServer;
|
||||
@@ -207,6 +213,11 @@ public class TetheringConfiguration {
|
||||
provisioningResponse = getResourceString(res,
|
||||
R.string.config_mobile_hotspot_provision_response);
|
||||
|
||||
PersistableBundle carrierConfigs = getCarrierConfig(ctx, activeDataSubId);
|
||||
isCarrierSupportTethering = carrierConfigAffirmsCarrierSupport(carrierConfigs);
|
||||
isCarrierConfigAffirmsEntitlementCheckRequired =
|
||||
carrierConfigAffirmsEntitlementCheckRequired(carrierConfigs);
|
||||
|
||||
mOffloadPollInterval = getResourceInteger(res,
|
||||
R.integer.config_tether_offload_poll_interval,
|
||||
DEFAULT_TETHER_OFFLOAD_POLL_INTERVAL_MS);
|
||||
@@ -329,6 +340,10 @@ public class TetheringConfiguration {
|
||||
pw.print("provisioningAppNoUi: ");
|
||||
pw.println(provisioningAppNoUi);
|
||||
|
||||
pw.println("isCarrierSupportTethering: " + isCarrierSupportTethering);
|
||||
pw.println("isCarrierConfigAffirmsEntitlementCheckRequired: "
|
||||
+ isCarrierConfigAffirmsEntitlementCheckRequired);
|
||||
|
||||
pw.print("enableBpfOffload: ");
|
||||
pw.println(mEnableBpfOffload);
|
||||
|
||||
@@ -361,6 +376,9 @@ public class TetheringConfiguration {
|
||||
toIntArray(preferredUpstreamIfaceTypes)));
|
||||
sj.add(String.format("provisioningApp:%s", makeString(provisioningApp)));
|
||||
sj.add(String.format("provisioningAppNoUi:%s", provisioningAppNoUi));
|
||||
sj.add(String.format("isCarrierSupportTethering:%s", isCarrierSupportTethering));
|
||||
sj.add(String.format("isCarrierConfigAffirmsEntitlementCheckRequired:%s",
|
||||
isCarrierConfigAffirmsEntitlementCheckRequired));
|
||||
sj.add(String.format("enableBpfOffload:%s", mEnableBpfOffload));
|
||||
sj.add(String.format("enableLegacyDhcpServer:%s", mEnableLegacyDhcpServer));
|
||||
return String.format("TetheringConfiguration{%s}", sj.toString());
|
||||
@@ -596,6 +614,39 @@ public class TetheringConfiguration {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean carrierConfigAffirmsEntitlementCheckRequired(
|
||||
PersistableBundle carrierConfig) {
|
||||
if (carrierConfig == null) {
|
||||
return true;
|
||||
}
|
||||
return carrierConfig.getBoolean(
|
||||
CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, true);
|
||||
}
|
||||
|
||||
private static boolean carrierConfigAffirmsCarrierSupport(PersistableBundle carrierConfig) {
|
||||
if (!SdkLevel.isAtLeastT() || carrierConfig == null) {
|
||||
return true;
|
||||
}
|
||||
return carrierConfig.getBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get carrier configuration bundle.
|
||||
*/
|
||||
public static PersistableBundle getCarrierConfig(Context context, int activeDataSubId) {
|
||||
final CarrierConfigManager configManager =
|
||||
context.getSystemService(CarrierConfigManager.class);
|
||||
if (configManager == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PersistableBundle carrierConfig = configManager.getConfigForSubId(activeDataSubId);
|
||||
if (CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
|
||||
return carrierConfig;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this TetheringConfiguration to a TetheringConfigurationParcel.
|
||||
*/
|
||||
|
||||
@@ -303,33 +303,6 @@ public final class EntitlementManagerTest {
|
||||
assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toleratesCarrierConfigManagerMissing() {
|
||||
setupForRequiredProvisioning();
|
||||
mockService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class, null);
|
||||
mConfig = new FakeTetheringConfiguration(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(mConfig));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toleratesCarrierConfigMissing() {
|
||||
setupForRequiredProvisioning();
|
||||
when(mCarrierConfigManager.getConfig()).thenReturn(null);
|
||||
mConfig = new FakeTetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
|
||||
// We still have a provisioning app configured, so still require provisioning.
|
||||
assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toleratesCarrierConfigNotLoaded() {
|
||||
setupForRequiredProvisioning();
|
||||
mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
|
||||
// We still have a provisioning app configured, so still require provisioning.
|
||||
assertTrue(mEnMgr.isTetherProvisioningRequired(mConfig));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void provisioningNotRequiredWhenAppNotFound() {
|
||||
setupForRequiredProvisioning();
|
||||
@@ -706,8 +679,8 @@ public final class EntitlementManagerTest {
|
||||
@IgnoreUpTo(SC_V2)
|
||||
public void requestLatestTetheringEntitlementResult_carrierDoesNotSupport_noProvisionCount()
|
||||
throws Exception {
|
||||
setupForRequiredProvisioning();
|
||||
setupCarrierConfig(false);
|
||||
setupForRequiredProvisioning();
|
||||
mEnMgr.fakeEntitlementResult = TETHER_ERROR_NO_ERROR;
|
||||
ResultReceiver receiver = new ResultReceiver(null) {
|
||||
@Override
|
||||
@@ -735,6 +708,7 @@ public final class EntitlementManagerTest {
|
||||
mEnMgr.notifyUpstream(false);
|
||||
mLooper.dispatchAll();
|
||||
setupCarrierConfig(false);
|
||||
mConfig = new FakeTetheringConfiguration(mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
|
||||
mEnMgr.reevaluateSimCardProvisioning(mConfig);
|
||||
|
||||
// Turn on upstream.
|
||||
@@ -749,8 +723,8 @@ public final class EntitlementManagerTest {
|
||||
@IgnoreUpTo(SC_V2)
|
||||
public void startProvisioningIfNeeded_carrierUnsupport()
|
||||
throws Exception {
|
||||
setupForRequiredProvisioning();
|
||||
setupCarrierConfig(false);
|
||||
setupForRequiredProvisioning();
|
||||
mEnMgr.startProvisioningIfNeeded(TETHERING_WIFI, true);
|
||||
verify(mTetherProvisioningFailedListener, never())
|
||||
.onTetherProvisioningFailed(TETHERING_WIFI, "Carrier does not support.");
|
||||
|
||||
@@ -22,10 +22,13 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
|
||||
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||
import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
|
||||
import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
|
||||
import static android.telephony.CarrierConfigManager.KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL;
|
||||
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
import static com.android.networkstack.apishim.ConstantsShim.KEY_CARRIER_SUPPORTS_TETHERING_BOOL;
|
||||
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_FORCE_USB_FUNCTIONS;
|
||||
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_NCM_FUNCTION;
|
||||
import static com.android.networkstack.tethering.TetheringConfiguration.TETHER_USB_RNDIS_FUNCTION;
|
||||
@@ -46,8 +49,10 @@ import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.net.util.SharedLog;
|
||||
import android.os.Build;
|
||||
import android.os.PersistableBundle;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.mock.MockContentResolver;
|
||||
|
||||
@@ -56,6 +61,7 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.internal.util.test.BroadcastInterceptingContext;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.modules.utils.build.SdkLevel;
|
||||
import com.android.net.module.util.DeviceConfigUtils;
|
||||
import com.android.testutils.DevSdkIgnoreRule;
|
||||
import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter;
|
||||
@@ -88,6 +94,7 @@ public class TetheringConfigurationTest {
|
||||
private static final long TEST_PACKAGE_VERSION = 1234L;
|
||||
@Mock private ApplicationInfo mApplicationInfo;
|
||||
@Mock private Context mContext;
|
||||
@Mock private CarrierConfigManager mCarrierConfigManager;
|
||||
@Mock private TelephonyManager mTelephonyManager;
|
||||
@Mock private Resources mResources;
|
||||
@Mock private Resources mResourcesForSubId;
|
||||
@@ -97,6 +104,7 @@ public class TetheringConfigurationTest {
|
||||
private boolean mHasTelephonyManager;
|
||||
private MockitoSession mMockingSession;
|
||||
private MockContentResolver mContentResolver;
|
||||
private final PersistableBundle mCarrierConfig = new PersistableBundle();
|
||||
|
||||
private class MockTetheringConfiguration extends TetheringConfiguration {
|
||||
MockTetheringConfiguration(Context ctx, SharedLog log, int id) {
|
||||
@@ -474,6 +482,56 @@ public class TetheringConfigurationTest {
|
||||
PROVISIONING_APP_RESPONSE);
|
||||
}
|
||||
|
||||
private <T> void mockService(String serviceName, Class<T> serviceClass, T service) {
|
||||
when(mMockContext.getSystemServiceName(serviceClass)).thenReturn(serviceName);
|
||||
when(mMockContext.getSystemService(serviceName)).thenReturn(service);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCarrierConfigBySubId_noCarrierConfigManager_configsAreDefault() {
|
||||
// Act like the CarrierConfigManager is present and ready unless told otherwise.
|
||||
mockService(Context.CARRIER_CONFIG_SERVICE,
|
||||
CarrierConfigManager.class, null);
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(
|
||||
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
assertTrue(cfg.isCarrierSupportTethering);
|
||||
assertTrue(cfg.isCarrierConfigAffirmsEntitlementCheckRequired);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCarrierConfigBySubId_carrierConfigMissing_configsAreDefault() {
|
||||
// Act like the CarrierConfigManager is present and ready unless told otherwise.
|
||||
mockService(Context.CARRIER_CONFIG_SERVICE,
|
||||
CarrierConfigManager.class, mCarrierConfigManager);
|
||||
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(null);
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(
|
||||
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
assertTrue(cfg.isCarrierSupportTethering);
|
||||
assertTrue(cfg.isCarrierConfigAffirmsEntitlementCheckRequired);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetCarrierConfigBySubId_hasConfigs_carrierUnsupportAndCheckNotRequired() {
|
||||
mockService(Context.CARRIER_CONFIG_SERVICE,
|
||||
CarrierConfigManager.class, mCarrierConfigManager);
|
||||
mCarrierConfig.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
|
||||
mCarrierConfig.putBoolean(KEY_REQUIRE_ENTITLEMENT_CHECKS_BOOL, false);
|
||||
mCarrierConfig.putBoolean(KEY_CARRIER_SUPPORTS_TETHERING_BOOL, false);
|
||||
when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mCarrierConfig);
|
||||
final TetheringConfiguration cfg = new TetheringConfiguration(
|
||||
mMockContext, mLog, INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
if (SdkLevel.isAtLeastT()) {
|
||||
assertFalse(cfg.isCarrierSupportTethering);
|
||||
} else {
|
||||
assertTrue(cfg.isCarrierSupportTethering);
|
||||
}
|
||||
assertFalse(cfg.isCarrierConfigAffirmsEntitlementCheckRequired);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnableLegacyWifiP2PAddress() throws Exception {
|
||||
final TetheringConfiguration defaultCfg = new TetheringConfiguration(
|
||||
|
||||
Reference in New Issue
Block a user