diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl b/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl index fdf0d16057..89f38132ff 100644 --- a/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl +++ b/Tethering/common/TetheringLib/src/android/net/TetheringConfigurationParcel.aidl @@ -17,7 +17,7 @@ package android.net; /** - * Configuration details for a tethering. + * Configuration details for tethering. * @hide */ parcelable TetheringConfigurationParcel { diff --git a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java index 9e8726edf0..eb0d443f4b 100644 --- a/Tethering/common/TetheringLib/src/android/net/TetheringManager.java +++ b/Tethering/common/TetheringLib/src/android/net/TetheringManager.java @@ -168,11 +168,12 @@ public class TetheringManager { * #getTetherableIfaces() to ensure corresponding interface is available for * tethering before calling #tether(). * - * TODO: Deprecate this API. The only usages should be in PanService and Wifi P2P which + * @deprecated The only usages should be in PanService and Wifi P2P which * need direct access. * * {@hide} */ + @Deprecated public int tether(@NonNull String iface) { try { mConnector.tether(iface); @@ -185,8 +186,10 @@ public class TetheringManager { /** * Stop tethering the named interface. * + * @deprecated * {@hide} */ + @Deprecated public int untether(@NonNull String iface) { try { mConnector.untether(iface); @@ -202,9 +205,10 @@ public class TetheringManager { * encapsulate proper entitlement logic. If the API is used and an entitlement check is needed, * downstream USB tethering will be enabled but will not have any upstream. * - * @Deprecated + * @deprecated * {@hide} */ + @Deprecated public int setUsbTethering(boolean enable) { try { mConnector.setUsbTethering(enable); @@ -386,8 +390,10 @@ public class TetheringManager { /** * Get the set of tethered dhcp ranges. * + * @deprecated This API just return the default value which is not used in DhcpServer. * {@hide} */ + @Deprecated public @NonNull String[] getTetheredDhcpRanges() { if (!mCallback.awaitCallbackCreation()) { throw new NullPointerException("callback was not ready yet"); diff --git a/Tethering/src/com/android/server/connectivity/tethering/Tethering.java b/Tethering/src/com/android/server/connectivity/tethering/Tethering.java index 058fb4fe98..f1228129cd 100644 --- a/Tethering/src/com/android/server/connectivity/tethering/Tethering.java +++ b/Tethering/src/com/android/server/connectivity/tethering/Tethering.java @@ -93,8 +93,6 @@ import android.os.RemoteException; import android.os.ResultReceiver; import android.os.UserHandle; import android.os.UserManager; -import android.os.UserManagerInternal; -import android.os.UserManagerInternal.UserRestrictionsListener; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -111,7 +109,6 @@ import com.android.internal.util.MessageUtils; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; -import com.android.server.LocalServices; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -188,6 +185,7 @@ public class Tethering { private final PhoneStateListener mPhoneStateListener; private final INetd mNetd; private final NetdCallback mNetdCallback; + private final UserRestrictionActionListener mTetheringRestriction; private int mActiveDataSubId = INVALID_SUBSCRIPTION_ID; // All the usage of mTetherInternalCallback should run in the same thread. private ITetherInternalCallback mTetherInternalCallback = null; @@ -280,6 +278,10 @@ public class Tethering { mLog.e("Unable to register netd UnsolicitedEventListener"); } + final UserManager userManager = (UserManager) mContext.getSystemService( + Context.USER_SERVICE); + mTetheringRestriction = new UserRestrictionActionListener(userManager, this); + // Load tethering configuration. updateConfiguration(); @@ -298,6 +300,7 @@ public class Tethering { filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); + filter.addAction(UserManager.ACTION_USER_RESTRICTIONS_CHANGED); mContext.registerReceiver(mStateReceiver, filter, null, handler); filter = new IntentFilter(); @@ -306,11 +309,6 @@ public class Tethering { filter.addDataScheme("file"); mContext.registerReceiver(mStateReceiver, filter, null, handler); - final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class); - // This check is useful only for some unit tests; example: ConnectivityServiceTest. - if (umi != null) { - umi.addUserRestrictionsListener(new TetheringUserRestrictionListener(this)); - } } private WifiManager getWifiManager() { @@ -717,8 +715,8 @@ public class Tethering { } if (mTetheredNotificationBuilder == null) { - mTetheredNotificationBuilder = - new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS); + mTetheredNotificationBuilder = new Notification.Builder(mContext, + SystemNotificationChannels.NETWORK_STATUS); mTetheredNotificationBuilder.setWhen(0) .setOngoing(true) .setColor(mContext.getColor( @@ -764,6 +762,9 @@ public class Tethering { } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) { mLog.log("OBSERVED configuration changed"); updateConfiguration(); + } else if (action.equals(UserManager.ACTION_USER_RESTRICTIONS_CHANGED)) { + mLog.log("OBSERVED user restrictions changed"); + handleUserRestrictionAction(); } } @@ -870,25 +871,35 @@ public class Tethering { } } } + + private void handleUserRestrictionAction() { + mTetheringRestriction.onUserRestrictionsChanged(); + } } @VisibleForTesting - protected static class TetheringUserRestrictionListener implements UserRestrictionsListener { + protected static class UserRestrictionActionListener { + private final UserManager mUserManager; private final Tethering mWrapper; + public boolean mDisallowTethering; - public TetheringUserRestrictionListener(Tethering wrapper) { + public UserRestrictionActionListener(UserManager um, Tethering wrapper) { + mUserManager = um; mWrapper = wrapper; + mDisallowTethering = false; } - public void onUserRestrictionsChanged(int userId, - Bundle newRestrictions, - Bundle prevRestrictions) { + public void 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. + final Bundle restrictions = mUserManager.getUserRestrictions(); final boolean newlyDisallowed = - newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); - final boolean previouslyDisallowed = - prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); - final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed); + restrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING); + final boolean prevDisallowed = mDisallowTethering; + mDisallowTethering = newlyDisallowed; + final boolean tetheringDisallowedChanged = (newlyDisallowed != prevDisallowed); if (!tetheringDisallowedChanged) { return; } diff --git a/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java b/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java index 4f6f61bf95..0273ed3586 100644 --- a/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java +++ b/Tethering/tests/unit/src/com/android/server/connectivity/tethering/TetheringTest.java @@ -166,6 +166,7 @@ public class TetheringTest { @Mock private RouterAdvertisementDaemon mRouterAdvertisementDaemon; @Mock private IDhcpServer mDhcpServer; @Mock private INetd mNetd; + @Mock private UserManager mUserManager; private final MockIpServerDependencies mIpServerDependencies = spy(new MockIpServerDependencies()); @@ -214,6 +215,7 @@ public class TetheringTest { if (Context.WIFI_SERVICE.equals(name)) return mWifiManager; if (Context.USB_SERVICE.equals(name)) return mUsbManager; if (Context.TELEPHONY_SERVICE.equals(name)) return mTelephonyManager; + if (Context.USER_SERVICE.equals(name)) return mUserManager; return super.getSystemService(name); } @@ -954,26 +956,26 @@ public class TetheringTest { verifyNoMoreInteractions(mNMService); } - private void userRestrictionsListenerBehaviour( + private void runUserRestrictionsChange( boolean currentDisallow, boolean nextDisallow, String[] activeTetheringIfacesList, int expectedInteractionsWithShowNotification) throws Exception { - final int userId = 0; - final Bundle currRestrictions = new Bundle(); final Bundle newRestrictions = new Bundle(); - Tethering tethering = mock(Tethering.class); - Tethering.TetheringUserRestrictionListener turl = - new Tethering.TetheringUserRestrictionListener(tethering); - - currRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, currentDisallow); newRestrictions.putBoolean(UserManager.DISALLOW_CONFIG_TETHERING, nextDisallow); - when(tethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList); + final Tethering mockTethering = mock(Tethering.class); + when(mockTethering.getTetheredIfaces()).thenReturn(activeTetheringIfacesList); + when(mUserManager.getUserRestrictions()).thenReturn(newRestrictions); - turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions); + final Tethering.UserRestrictionActionListener ural = + new Tethering.UserRestrictionActionListener(mUserManager, mockTethering); + ural.mDisallowTethering = currentDisallow; - verify(tethering, times(expectedInteractionsWithShowNotification)) + ural.onUserRestrictionsChanged(); + + verify(mockTethering, times(expectedInteractionsWithShowNotification)) .showTetheredNotification(anyInt(), eq(false)); - verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll(); + verify(mockTethering, times(expectedInteractionsWithShowNotification)) + .untetherAll(); } @Test @@ -983,7 +985,7 @@ public class TetheringTest { final boolean nextDisallow = true; final int expectedInteractionsWithShowNotification = 0; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, emptyActiveIfacesList, expectedInteractionsWithShowNotification); } @@ -994,7 +996,7 @@ public class TetheringTest { final boolean nextDisallow = true; final int expectedInteractionsWithShowNotification = 1; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, expectedInteractionsWithShowNotification); } @@ -1005,7 +1007,7 @@ public class TetheringTest { final boolean nextDisallow = false; final int expectedInteractionsWithShowNotification = 0; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, expectedInteractionsWithShowNotification); } @@ -1016,7 +1018,7 @@ public class TetheringTest { final boolean nextDisallow = false; final int expectedInteractionsWithShowNotification = 0; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, expectedInteractionsWithShowNotification); } @@ -1027,13 +1029,13 @@ public class TetheringTest { boolean currDisallow = true; boolean nextDisallow = true; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, expectedInteractionsWithShowNotification); currDisallow = false; nextDisallow = false; - userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList, + runUserRestrictionsChange(currDisallow, nextDisallow, nonEmptyActiveIfacesList, expectedInteractionsWithShowNotification); }