updateSupportedDownstreams when tethering allowed is changed
There are three configuration could affect tethering allowed:
1. user restriction
2. tether_supported settings
3. ro.tether.denied system properties
When user restricted or tether supported setting change, updating
supported downstreams.
ro.tether.denied is read only properties, so it won't be changed runtime.
Also correct the unit test that there is no TetheringConfiguration change when settings or user restriction change.
Bug: 184996041
Bug: 239500515
Test: atest TetheringTests
Change-Id: I8dfcc42de9787a5e9ba19b69db9444c14ace56f0
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index 5191bb7..0d1b22e 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -97,6 +97,7 @@
import android.net.TetheringInterface;
import android.net.TetheringManager.TetheringRequest;
import android.net.TetheringRequestParcel;
+import android.net.Uri;
import android.net.ip.IpServer;
import android.net.wifi.WifiClient;
import android.net.wifi.WifiManager;
@@ -343,9 +344,8 @@
mEntitlementMgr.reevaluateSimCardProvisioning(mConfig);
});
- mSettingsObserver = new SettingsObserver(mHandler);
- mContext.getContentResolver().registerContentObserver(
- Settings.Global.getUriFor(TETHER_FORCE_USB_FUNCTIONS), false, mSettingsObserver);
+ mSettingsObserver = new SettingsObserver(mContext, mHandler);
+ mSettingsObserver.startObserve();
mStateReceiver = new StateReceiver();
@@ -397,18 +397,42 @@
}
private class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
+ private final Uri mForceUsbFunctions;
+ private final Uri mTetherSupported;
+ private final Context mContext;
+
+ SettingsObserver(Context ctx, Handler handler) {
super(handler);
+ mContext = ctx;
+ mForceUsbFunctions = Settings.Global.getUriFor(TETHER_FORCE_USB_FUNCTIONS);
+ mTetherSupported = Settings.Global.getUriFor(Settings.Global.TETHER_SUPPORTED);
+ }
+
+ public void startObserve() {
+ mContext.getContentResolver().registerContentObserver(mForceUsbFunctions, false, this);
+ mContext.getContentResolver().registerContentObserver(mTetherSupported, false, this);
}
@Override
public void onChange(boolean selfChange) {
- mLog.i("OBSERVED Settings change");
- final boolean isUsingNcm = mConfig.isUsingNcm();
- updateConfiguration();
- if (isUsingNcm != mConfig.isUsingNcm()) {
- stopTetheringInternal(TETHERING_USB);
- stopTetheringInternal(TETHERING_NCM);
+ Log.wtf(TAG, "Should never be reached.");
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (mForceUsbFunctions.equals(uri)) {
+ mLog.i("OBSERVED TETHER_FORCE_USB_FUNCTIONS settings change");
+ final boolean isUsingNcm = mConfig.isUsingNcm();
+ updateConfiguration();
+ if (isUsingNcm != mConfig.isUsingNcm()) {
+ stopTetheringInternal(TETHERING_USB);
+ stopTetheringInternal(TETHERING_NCM);
+ }
+ } else if (mTetherSupported.equals(uri)) {
+ mLog.i("OBSERVED TETHER_SUPPORTED settings change");
+ updateSupportedDownstreams(mConfig);
+ } else {
+ mLog.e("Unexpected settings change: " + uri);
}
}
}
@@ -1322,7 +1346,9 @@
}
private void handleUserRestrictionAction() {
- mTetheringRestriction.onUserRestrictionsChanged();
+ if (mTetheringRestriction.onUserRestrictionsChanged()) {
+ updateSupportedDownstreams(mConfig);
+ }
}
private void handleDataSaverChanged() {
@@ -1350,6 +1376,8 @@
return getTetheredIfaces().length > 0;
}
+ // TODO: Refine TetheringTest then remove UserRestrictionActionListener class and handle
+ // onUserRestrictionsChanged inside Tethering#handleUserRestrictionAction directly.
@VisibleForTesting
protected static class UserRestrictionActionListener {
private final UserManager mUserMgr;
@@ -1365,7 +1393,8 @@
mDisallowTethering = false;
}
- public void onUserRestrictionsChanged() {
+ // return whether tethering disallowed is changed.
+ public boolean onUserRestrictionsChanged() {
// getUserRestrictions gets restriction for this process' user, which is the primary
// user. This is fine because DISALLOW_CONFIG_TETHERING can only be set on the primary
// user. See UserManager.DISALLOW_CONFIG_TETHERING.
@@ -1376,15 +1405,13 @@
mDisallowTethering = newlyDisallowed;
final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed);
- if (!tetheringDisallowedChanged) {
- return;
- }
+ if (!tetheringDisallowedChanged) return false;
if (!newlyDisallowed) {
// Clear the restricted notification when user is allowed to have tethering
// function.
mNotificationUpdater.tetheringRestrictionLifted();
- return;
+ return true;
}
if (mTethering.isTetheringActive()) {
@@ -1395,6 +1422,8 @@
// Untether from all downstreams since tethering is disallowed.
mTethering.untetherAll();
}
+
+ return true;
// TODO(b/148139325): send tetheringSupported on restriction change
}
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
index 66ad167..a36d67f 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/TetheringTest.java
@@ -2899,9 +2899,13 @@
}
private void forceUsbTetheringUse(final int function) {
- Settings.Global.putInt(mContentResolver, TETHER_FORCE_USB_FUNCTIONS, function);
+ setSetting(TETHER_FORCE_USB_FUNCTIONS, function);
+ }
+
+ private void setSetting(final String key, final int value) {
+ Settings.Global.putInt(mContentResolver, key, value);
final ContentObserver observer = mTethering.getSettingsObserverForTest();
- observer.onChange(false /* selfChange */);
+ observer.onChange(false /* selfChange */, Settings.Global.getUriFor(key));
mLooper.dispatchAll();
}
@@ -2957,74 +2961,86 @@
TETHERING_WIFI_P2P, TETHERING_BLUETOOTH, TETHERING_ETHERNET });
}
+ private void setUserRestricted(boolean restricted) {
+ final Bundle restrictions = new Bundle();
+ restrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, restricted);
+ when(mUserManager.getUserRestrictions()).thenReturn(restrictions);
+ when(mUserManager.hasUserRestriction(
+ UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(restricted);
+
+ final Intent intent = new Intent(UserManager.ACTION_USER_RESTRICTIONS_CHANGED);
+ mServiceContext.sendBroadcastAsUser(intent, UserHandle.ALL);
+ mLooper.dispatchAll();
+ }
+
@Test
public void testTetheringSupported() throws Exception {
final ArraySet<Integer> expectedTypes = getAllSupportedTetheringTypes();
// Check tethering is supported after initialization.
- setTetheringSupported(true /* supported */);
TestTetheringEventCallback callback = new TestTetheringEventCallback();
mTethering.registerTetheringEventCallback(callback);
mLooper.dispatchAll();
- updateConfigAndVerifySupported(callback, expectedTypes);
+ verifySupported(callback, expectedTypes);
- // Could disable tethering supported by settings.
- Settings.Global.putInt(mContentResolver, Settings.Global.TETHER_SUPPORTED, 0);
- updateConfigAndVerifySupported(callback, new ArraySet<>());
+ // Could change tethering supported by settings.
+ setSetting(Settings.Global.TETHER_SUPPORTED, 0);
+ verifySupported(callback, new ArraySet<>());
+ setSetting(Settings.Global.TETHER_SUPPORTED, 1);
+ verifySupported(callback, expectedTypes);
- // Could disable tethering supported by user restriction.
- setTetheringSupported(true /* supported */);
- updateConfigAndVerifySupported(callback, expectedTypes);
- when(mUserManager.hasUserRestriction(
- UserManager.DISALLOW_CONFIG_TETHERING)).thenReturn(true);
- updateConfigAndVerifySupported(callback, new ArraySet<>());
+ // Could change tethering supported by user restriction.
+ setUserRestricted(true /* restricted */);
+ verifySupported(callback, new ArraySet<>());
+ setUserRestricted(false /* restricted */);
+ verifySupported(callback, expectedTypes);
- // Tethering is supported if it has any supported downstream.
- setTetheringSupported(true /* supported */);
- updateConfigAndVerifySupported(callback, expectedTypes);
// Usb tethering is not supported:
expectedTypes.remove(TETHERING_USB);
when(mResources.getStringArray(R.array.config_tether_usb_regexs))
.thenReturn(new String[0]);
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, expectedTypes);
// Wifi tethering is not supported:
expectedTypes.remove(TETHERING_WIFI);
when(mResources.getStringArray(R.array.config_tether_wifi_regexs))
.thenReturn(new String[0]);
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, expectedTypes);
// Bluetooth tethering is not supported:
expectedTypes.remove(TETHERING_BLUETOOTH);
when(mResources.getStringArray(R.array.config_tether_bluetooth_regexs))
.thenReturn(new String[0]);
if (isAtLeastT()) {
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, expectedTypes);
// P2p tethering is not supported:
expectedTypes.remove(TETHERING_WIFI_P2P);
when(mResources.getStringArray(R.array.config_tether_wifi_p2p_regexs))
.thenReturn(new String[0]);
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, expectedTypes);
// Ncm tethering is not supported:
expectedTypes.remove(TETHERING_NCM);
when(mResources.getStringArray(R.array.config_tether_ncm_regexs))
.thenReturn(new String[0]);
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, expectedTypes);
// Ethernet tethering (last supported type) is not supported:
expectedTypes.remove(TETHERING_ETHERNET);
mForceEthernetServiceUnavailable = true;
- updateConfigAndVerifySupported(callback, new ArraySet<>());
-
+ sendConfigurationChanged();
+ verifySupported(callback, new ArraySet<>());
} else {
// If wifi, usb and bluetooth are all not supported, all the types are not supported.
- expectedTypes.clear();
- updateConfigAndVerifySupported(callback, expectedTypes);
+ sendConfigurationChanged();
+ verifySupported(callback, new ArraySet<>());
}
}
- private void updateConfigAndVerifySupported(final TestTetheringEventCallback callback,
+ private void verifySupported(final TestTetheringEventCallback callback,
final ArraySet<Integer> expectedTypes) {
- sendConfigurationChanged();
-
assertEquals(expectedTypes.size() > 0, mTethering.isTetheringSupported());
callback.expectSupportedTetheringTypes(expectedTypes);
}