Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9295c7d authored by Alexandru-andrei Rotaru's avatar Alexandru-andrei Rotaru Committed by Android (Google) Code Review
Browse files

Merge "Notify the user and turn off tethering when the service is disallowed."...

Merge "Notify the user and turn off tethering when the service is disallowed." into stage-aosp-master
parents 54c1b9e9 5469504e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3476,6 +3476,13 @@
    <string name="tethered_notification_title">Tethering or hotspot active</string>
    <string name="tethered_notification_message">Tap to set up.</string>

    <!-- Strings for tether disabling notification -->
    <!-- This notification is shown when tethering has been disabled on a user's device.
    The device is managed by the user's employer. Tethering can't be turned on unless the
    IT administrator allows it. The noun "admin" is another reference for "IT administrator." -->
    <string name="disable_tether_notification_title">Tethering is disabled</string>
    <string name="disable_tether_notification_message">Contact your admin for details</string>

    <!--  Strings for possible PreferenceActivity Back/Next buttons -->
    <string name="back_button_label">Back</string>
    <string name="next_button_label">Next</string>
+2 −0
Original line number Diff line number Diff line
@@ -1957,6 +1957,8 @@
  <java-symbol type="string" name="smv_process" />
  <java-symbol type="string" name="tethered_notification_message" />
  <java-symbol type="string" name="tethered_notification_title" />
  <java-symbol type="string" name="disable_tether_notification_message" />
  <java-symbol type="string" name="disable_tether_notification_title" />
  <java-symbol type="string" name="adb_debugging_notification_channel_tv" />
  <java-symbol type="string" name="usb_accessory_notification_title" />
  <java-symbol type="string" name="usb_mtp_notification_title" />
+60 −4
Original line number Diff line number Diff line
@@ -70,6 +70,9 @@ import android.os.Parcel;
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.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
@@ -89,6 +92,7 @@ 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 com.android.server.connectivity.tethering.IControlsTethering;
import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
import com.android.server.connectivity.tethering.OffloadController;
@@ -236,6 +240,13 @@ public class Tethering extends BaseNetworkObserver {
        filter.addDataScheme("file");
        mContext.registerReceiver(mStateReceiver, filter, null, smHandler);

        UserManagerInternal userManager = LocalServices.getService(UserManagerInternal.class);

        // this check is useful only for some unit tests; example: ConnectivityServiceTest
        if (userManager != null) {
            userManager.addUserRestrictionsListener(new TetheringUserRestrictionListener(this));
        }

        // load device config info
        updateConfiguration();
    }
@@ -710,6 +721,11 @@ public class Tethering extends BaseNetworkObserver {
    }

    private void showTetheredNotification(int id) {
        showTetheredNotification(id, true);
    }

    @VisibleForTesting
    protected void showTetheredNotification(int id, boolean tetheringOn) {
        NotificationManager notificationManager =
                (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager == null) {
@@ -746,9 +762,16 @@ public class Tethering extends BaseNetworkObserver {
                null, UserHandle.CURRENT);

        Resources r = Resources.getSystem();
        CharSequence title = r.getText(com.android.internal.R.string.tethered_notification_title);
        CharSequence message = r.getText(com.android.internal.R.string.
                tethered_notification_message);
        final CharSequence title;
        final CharSequence message;

        if (tetheringOn) {
            title = r.getText(com.android.internal.R.string.tethered_notification_title);
            message = r.getText(com.android.internal.R.string.tethered_notification_message);
        } else {
            title = r.getText(com.android.internal.R.string.disable_tether_notification_title);
            message = r.getText(com.android.internal.R.string.disable_tether_notification_message);
        }

        if (mTetheredNotificationBuilder == null) {
            mTetheredNotificationBuilder =
@@ -770,7 +793,8 @@ public class Tethering extends BaseNetworkObserver {
                mTetheredNotificationBuilder.buildInto(new Notification()), UserHandle.ALL);
    }

    private void clearTetheredNotification() {
    @VisibleForTesting
    protected void clearTetheredNotification() {
        NotificationManager notificationManager =
            (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        if (notificationManager != null && mLastNotificationId != 0) {
@@ -874,6 +898,38 @@ public class Tethering extends BaseNetworkObserver {
        }
    }

    @VisibleForTesting
    protected static class TetheringUserRestrictionListener implements UserRestrictionsListener {
        private final Tethering mWrapper;

        public TetheringUserRestrictionListener(Tethering wrapper) {
            mWrapper = wrapper;
        }

        public void onUserRestrictionsChanged(int userId,
                                              Bundle newRestrictions,
                                              Bundle prevRestrictions) {
            final boolean newlyDisallowed =
                    newRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
            final boolean previouslyDisallowed =
                    prevRestrictions.getBoolean(UserManager.DISALLOW_CONFIG_TETHERING);
            final boolean tetheringDisallowedChanged = (newlyDisallowed != previouslyDisallowed);

            if (!tetheringDisallowedChanged) {
                return;
            }

            mWrapper.clearTetheredNotification();
            final boolean isTetheringActiveOnDevice = (mWrapper.getTetheredIfaces().length != 0);

            if (newlyDisallowed && isTetheringActiveOnDevice) {
                mWrapper.showTetheredNotification(
                        com.android.internal.R.drawable.stat_sys_tether_general, false);
                mWrapper.untetherAll();
            }
        }
    }

    private void disableWifiIpServingLocked(String ifname, int apState) {
        mLog.log("Canceling WiFi tethering request - AP_STATE=" + apState);

+87 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
@@ -59,12 +60,14 @@ import android.net.NetworkRequest;
import android.net.util.SharedLog;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.test.TestLooper;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -558,6 +561,90 @@ public class TetheringTest {
        verifyNoMoreInteractions(mNMService);
    }

    private void userRestrictionsListenerBehaviour(
        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);

        turl.onUserRestrictionsChanged(userId, newRestrictions, currRestrictions);

        verify(tethering, times(expectedInteractionsWithShowNotification))
                .showTetheredNotification(anyInt(), eq(false));

        verify(tethering, times(expectedInteractionsWithShowNotification)).untetherAll();
    }

    @Test
    public void testDisallowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
        final String[] emptyActiveIfacesList = new String[]{};
        final boolean currDisallow = false;
        final boolean nextDisallow = true;
        final int expectedInteractionsWithShowNotification = 0;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, emptyActiveIfacesList,
                expectedInteractionsWithShowNotification);
    }

    @Test
    public void testDisallowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
        final boolean currDisallow = false;
        final boolean nextDisallow = true;
        final int expectedInteractionsWithShowNotification = 1;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
                expectedInteractionsWithShowNotification);
    }

    @Test
    public void testAllowTetheringWhenNoTetheringInterfaceIsActive() throws Exception {
        final String[] nonEmptyActiveIfacesList = new String[]{};
        final boolean currDisallow = true;
        final boolean nextDisallow = false;
        final int expectedInteractionsWithShowNotification = 0;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
                expectedInteractionsWithShowNotification);
    }

    @Test
    public void testAllowTetheringWhenAtLeastOneTetheringInterfaceIsActive() throws Exception {
        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
        final boolean currDisallow = true;
        final boolean nextDisallow = false;
        final int expectedInteractionsWithShowNotification = 0;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
                expectedInteractionsWithShowNotification);
    }

    @Test
    public void testDisallowTetheringUnchanged() throws Exception {
        final String[] nonEmptyActiveIfacesList = new String[]{mTestIfname};
        final int expectedInteractionsWithShowNotification = 0;
        boolean currDisallow = true;
        boolean nextDisallow = true;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
                expectedInteractionsWithShowNotification);

        currDisallow = false;
        nextDisallow = false;

        userRestrictionsListenerBehaviour(currDisallow, nextDisallow, nonEmptyActiveIfacesList,
                expectedInteractionsWithShowNotification);
    }


    // TODO: Test that a request for hotspot mode doesn't interfere with an
    // already operating tethering mode interface.
}