Pass entitlement configuration to Settings for entitlement check

Tethering resource configuration is move from framwork to tethering
module. Since tethering resource would not be accessible from outside
of tethering module, EntitlementManager would tell Settings the
entitlement configuration via intent extra when run entitlement check.

Bug: 146918263
Test: atest TetheringTests
Change-Id: I6f23553bb1da5f0b767f920b32a86fafb9e00b9e
This commit is contained in:
markchien
2020-06-08 11:30:18 +08:00
parent 7c538fa7ff
commit 217d7b01f8
5 changed files with 122 additions and 22 deletions

View File

@@ -37,8 +37,8 @@ public final class TetheringConstants {
private TetheringConstants() { }
/**
* Extra used for communicating with the TetherService. Includes the type of tethering to
* enable if any.
* Extra used for communicating with the TetherService and TetherProvisioningActivity.
* Includes the type of tethering to enable if any.
*/
public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
/**
@@ -56,8 +56,38 @@ public final class TetheringConstants {
*/
public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
/**
* Extra used for communicating with the TetherService. Contains the {@link ResultReceiver}
* which will receive provisioning results. Can be left empty.
* Extra used for communicating with the TetherService and TetherProvisioningActivity.
* Contains the {@link ResultReceiver} which will receive provisioning results.
* Can not be empty.
*/
public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
/**
* Extra used for communicating with the TetherService and TetherProvisioningActivity.
* Contains the subId of current active cellular upstream.
* @hide
*/
public static final String EXTRA_TETHER_SUBID = "android.net.extra.TETHER_SUBID";
/**
* Extra used for telling TetherProvisioningActivity the entitlement package name and class
* name to start UI entitlement check.
* @hide
*/
public static final String EXTRA_TETHER_UI_PROVISIONING_APP_NAME =
"android.net.extra.TETHER_UI_PROVISIONING_APP_NAME";
/**
* Extra used for telling TetherService the intent action to start silent entitlement check.
* @hide
*/
public static final String EXTRA_TETHER_SILENT_PROVISIONING_ACTION =
"android.net.extra.TETHER_SILENT_PROVISIONING_ACTION";
/**
* Extra used for TetherService to receive the response of provisioning check.
* @hide
*/
public static final String EXTRA_TETHER_PROVISIONING_RESPONSE =
"android.net.extra.TETHER_PROVISIONING_RESPONSE";
}

View File

@@ -19,6 +19,10 @@ package com.android.networkstack.tethering;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_INVALID;
@@ -69,7 +73,6 @@ public class EntitlementManager {
protected static final String DISABLE_PROVISIONING_SYSPROP_KEY = "net.tethering.noprovisioning";
private static final String ACTION_PROVISIONING_ALARM =
"com.android.networkstack.tethering.PROVISIONING_RECHECK_ALARM";
private static final String EXTRA_SUBID = "subId";
private final ComponentName mSilentProvisioningService;
private static final int MS_PER_HOUR = 60 * 60 * 1000;
@@ -197,9 +200,9 @@ public class EntitlementManager {
// till upstream change to cellular.
if (mUsingCellularAsUpstream) {
if (showProvisioningUi) {
runUiTetherProvisioning(downstreamType, config.activeDataSubId);
runUiTetherProvisioning(downstreamType, config);
} else {
runSilentTetherProvisioning(downstreamType, config.activeDataSubId);
runSilentTetherProvisioning(downstreamType, config);
}
mNeedReRunProvisioningUi = false;
} else {
@@ -262,9 +265,9 @@ public class EntitlementManager {
if (mCurrentEntitlementResults.indexOfKey(downstream) < 0) {
if (mNeedReRunProvisioningUi) {
mNeedReRunProvisioningUi = false;
runUiTetherProvisioning(downstream, config.activeDataSubId);
runUiTetherProvisioning(downstream, config);
} else {
runSilentTetherProvisioning(downstream, config.activeDataSubId);
runSilentTetherProvisioning(downstream, config);
}
}
}
@@ -361,7 +364,7 @@ public class EntitlementManager {
* @param subId default data subscription ID.
*/
@VisibleForTesting
protected void runSilentTetherProvisioning(int type, int subId) {
protected Intent runSilentTetherProvisioning(int type, final TetheringConfiguration config) {
if (DBG) mLog.i("runSilentTetherProvisioning: " + type);
// For silent provisioning, settings would stop tethering when entitlement fail.
ResultReceiver receiver = buildProxyReceiver(type, false/* notifyFail */, null);
@@ -369,17 +372,20 @@ public class EntitlementManager {
Intent intent = new Intent();
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_RUN_PROVISION, true);
intent.putExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION, config.provisioningAppNoUi);
intent.putExtra(EXTRA_TETHER_PROVISIONING_RESPONSE, config.provisioningResponse);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
intent.putExtra(EXTRA_SUBID, subId);
intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
intent.setComponent(mSilentProvisioningService);
// Only admin user can change tethering and SilentTetherProvisioning don't need to
// show UI, it is fine to always start setting's background service as system user.
mContext.startService(intent);
return intent;
}
private void runUiTetherProvisioning(int type, int subId) {
private void runUiTetherProvisioning(int type, final TetheringConfiguration config) {
ResultReceiver receiver = buildProxyReceiver(type, true/* notifyFail */, null);
runUiTetherProvisioning(type, subId, receiver);
runUiTetherProvisioning(type, config, receiver);
}
/**
@@ -389,17 +395,20 @@ public class EntitlementManager {
* @param receiver to receive entitlement check result.
*/
@VisibleForTesting
protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
protected Intent runUiTetherProvisioning(int type, final TetheringConfiguration config,
ResultReceiver receiver) {
if (DBG) mLog.i("runUiTetherProvisioning: " + type);
Intent intent = new Intent(Settings.ACTION_TETHER_PROVISIONING_UI);
intent.putExtra(EXTRA_ADD_TETHER_TYPE, type);
intent.putExtra(EXTRA_TETHER_UI_PROVISIONING_APP_NAME, config.provisioningApp);
intent.putExtra(EXTRA_PROVISION_CALLBACK, receiver);
intent.putExtra(EXTRA_SUBID, subId);
intent.putExtra(EXTRA_TETHER_SUBID, config.activeDataSubId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Only launch entitlement UI for system user. Entitlement UI should not appear for other
// user because only admin user is allowed to change tethering.
mContext.startActivity(intent);
return intent;
}
// Not needed to check if this don't run on the handler thread because it's private.
@@ -631,7 +640,7 @@ public class EntitlementManager {
receiver.send(cacheValue, null);
} else {
ResultReceiver proxy = buildProxyReceiver(downstream, false/* notifyFail */, receiver);
runUiTetherProvisioning(downstream, config.activeDataSubId, proxy);
runUiTetherProvisioning(downstream, config, proxy);
}
}
}

View File

@@ -107,6 +107,7 @@ public class TetheringConfiguration {
public final String[] provisioningApp;
public final String provisioningAppNoUi;
public final int provisioningCheckPeriod;
public final String provisioningResponse;
public final int activeDataSubId;
@@ -141,10 +142,13 @@ public class TetheringConfiguration {
enableLegacyDhcpServer = getEnableLegacyDhcpServer(res);
provisioningApp = getResourceStringArray(res, R.array.config_mobile_hotspot_provision_app);
provisioningAppNoUi = getProvisioningAppNoUi(res);
provisioningAppNoUi = getResourceString(res,
R.string.config_mobile_hotspot_provision_app_no_ui);
provisioningCheckPeriod = getResourceInteger(res,
R.integer.config_mobile_hotspot_provision_check_period,
0 /* No periodic re-check */);
provisioningResponse = getResourceString(res,
R.string.config_mobile_hotspot_provision_response);
mOffloadPollInterval = getResourceInteger(res,
R.integer.config_tether_offload_poll_interval,
@@ -337,9 +341,9 @@ public class TetheringConfiguration {
return copy(LEGACY_DHCP_DEFAULT_RANGE);
}
private static String getProvisioningAppNoUi(Resources res) {
private static String getResourceString(Resources res, final int resId) {
try {
return res.getString(R.string.config_mobile_hotspot_provision_app_no_ui);
return res.getString(resId);
} catch (Resources.NotFoundException e) {
return "";
}

View File

@@ -16,8 +16,16 @@
package com.android.networkstack.tethering;
import static android.net.TetheringConstants.EXTRA_ADD_TETHER_TYPE;
import static android.net.TetheringConstants.EXTRA_PROVISION_CALLBACK;
import static android.net.TetheringConstants.EXTRA_RUN_PROVISION;
import static android.net.TetheringConstants.EXTRA_TETHER_PROVISIONING_RESPONSE;
import static android.net.TetheringConstants.EXTRA_TETHER_SILENT_PROVISIONING_ACTION;
import static android.net.TetheringConstants.EXTRA_TETHER_SUBID;
import static android.net.TetheringConstants.EXTRA_TETHER_UI_PROVISIONING_APP_NAME;
import static android.net.TetheringManager.TETHERING_BLUETOOTH;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import static android.net.TetheringManager.TETHERING_INVALID;
import static android.net.TetheringManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_WIFI;
import static android.net.TetheringManager.TETHERING_WIFI_P2P;
@@ -44,6 +52,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.util.SharedLog;
import android.os.Bundle;
@@ -53,6 +62,7 @@ import android.os.ResultReceiver;
import android.os.SystemProperties;
import android.os.test.TestLooper;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import androidx.test.filters.SmallTest;
@@ -76,6 +86,7 @@ public final class EntitlementManagerTest {
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
private static final String PROVISIONING_APP_RESPONSE = "app_response";
@Mock private CarrierConfigManager mCarrierConfigManager;
@Mock private Context mContext;
@@ -122,15 +133,51 @@ public final class EntitlementManagerTest {
}
@Override
protected void runUiTetherProvisioning(int type, int subId, ResultReceiver receiver) {
protected Intent runUiTetherProvisioning(int type,
final TetheringConfiguration config, final ResultReceiver receiver) {
Intent intent = super.runUiTetherProvisioning(type, config, receiver);
assertUiTetherProvisioningIntent(type, config, receiver, intent);
uiProvisionCount++;
receiver.send(fakeEntitlementResult, null);
return intent;
}
private void assertUiTetherProvisioningIntent(int type, final TetheringConfiguration config,
final ResultReceiver receiver, final Intent intent) {
assertEquals(Settings.ACTION_TETHER_PROVISIONING_UI, intent.getAction());
assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
final String[] appName = intent.getStringArrayExtra(
EXTRA_TETHER_UI_PROVISIONING_APP_NAME);
assertEquals(PROVISIONING_APP_NAME.length, appName.length);
for (int i = 0; i < PROVISIONING_APP_NAME.length; i++) {
assertEquals(PROVISIONING_APP_NAME[i], appName[i]);
}
assertEquals(receiver, intent.getParcelableExtra(EXTRA_PROVISION_CALLBACK));
assertEquals(config.activeDataSubId,
intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
}
@Override
protected void runSilentTetherProvisioning(int type, int subId) {
protected Intent runSilentTetherProvisioning(int type,
final TetheringConfiguration config) {
Intent intent = super.runSilentTetherProvisioning(type, config);
assertSilentTetherProvisioning(type, config, intent);
silentProvisionCount++;
addDownstreamMapping(type, fakeEntitlementResult);
return intent;
}
private void assertSilentTetherProvisioning(int type, final TetheringConfiguration config,
final Intent intent) {
assertEquals(type, intent.getIntExtra(EXTRA_ADD_TETHER_TYPE, TETHERING_INVALID));
assertEquals(true, intent.getBooleanExtra(EXTRA_RUN_PROVISION, false));
assertEquals(PROVISIONING_NO_UI_APP_NAME,
intent.getStringExtra(EXTRA_TETHER_SILENT_PROVISIONING_ACTION));
assertEquals(PROVISIONING_APP_RESPONSE,
intent.getStringExtra(EXTRA_TETHER_PROVISIONING_RESPONSE));
assertTrue(intent.hasExtra(EXTRA_PROVISION_CALLBACK));
assertEquals(config.activeDataSubId,
intent.getIntExtra(EXTRA_TETHER_SUBID, INVALID_SUBSCRIPTION_ID));
}
}
@@ -187,6 +234,8 @@ public final class EntitlementManagerTest {
.thenReturn(PROVISIONING_APP_NAME);
when(mResources.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
.thenReturn(PROVISIONING_NO_UI_APP_NAME);
when(mResources.getString(R.string.config_mobile_hotspot_provision_response)).thenReturn(
PROVISIONING_APP_RESPONSE);
// Act like the CarrierConfigManager is present and ready unless told otherwise.
when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
.thenReturn(mCarrierConfigManager);

View File

@@ -61,6 +61,8 @@ public class TetheringConfigurationTest {
private final SharedLog mLog = new SharedLog("TetheringConfigurationTest");
private static final String[] PROVISIONING_APP_NAME = {"some", "app"};
private static final String PROVISIONING_NO_UI_APP_NAME = "no_ui_app";
private static final String PROVISIONING_APP_RESPONSE = "app_response";
@Mock private Context mContext;
@Mock private TelephonyManager mTelephonyManager;
@Mock private Resources mResources;
@@ -388,6 +390,8 @@ public class TetheringConfigurationTest {
new MockTetheringConfiguration(mMockContext, mLog, anyValidSubId);
assertEquals(mockCfg.provisioningApp[0], PROVISIONING_APP_NAME[0]);
assertEquals(mockCfg.provisioningApp[1], PROVISIONING_APP_NAME[1]);
assertEquals(mockCfg.provisioningAppNoUi, PROVISIONING_NO_UI_APP_NAME);
assertEquals(mockCfg.provisioningResponse, PROVISIONING_APP_RESPONSE);
}
private void setUpResourceForSubId() {
@@ -403,6 +407,10 @@ public class TetheringConfigurationTest {
new int[0]);
when(mResourcesForSubId.getStringArray(
R.array.config_mobile_hotspot_provision_app)).thenReturn(PROVISIONING_APP_NAME);
when(mResourcesForSubId.getString(R.string.config_mobile_hotspot_provision_app_no_ui))
.thenReturn(PROVISIONING_NO_UI_APP_NAME);
when(mResourcesForSubId.getString(
R.string.config_mobile_hotspot_provision_response)).thenReturn(
PROVISIONING_APP_RESPONSE);
}
}