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

Commit 0e61baa0 authored by Erik Kline's avatar Erik Kline
Browse files

Always allow Ethernet to be an upstream

If there are any upstream types defined at all, make sure that
either TYPE_ETHERNET is included somewhere within the sorted list
or force it to be at the front.

Test: as follows
    - built
    - flashed
    - booted
    - runtest frameworks-net passes
Bug: 32163131
Bug: 36076442
Change-Id: Ie61d1358f73d518de23f6ca48ca2765ca14a1067
parent 1bfccadc
Loading
Loading
Loading
Loading
+27 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.connectivity.tethering;

import static android.content.Context.TELEPHONY_SERVICE;
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
@@ -208,29 +209,26 @@ public class TetheringConfiguration {
        // *always* an upstream, regardless of the upstream interface types
        // specified by configuration resources.
        if (dunCheck == DUN_REQUIRED) {
            if (!upstreamIfaceTypes.contains(TYPE_MOBILE_DUN)) {
                upstreamIfaceTypes.add(TYPE_MOBILE_DUN);
            }
            appendIfNotPresent(upstreamIfaceTypes, TYPE_MOBILE_DUN);
        } else if (dunCheck == DUN_NOT_REQUIRED) {
            if (!upstreamIfaceTypes.contains(TYPE_MOBILE)) {
                upstreamIfaceTypes.add(TYPE_MOBILE);
            }
            if (!upstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI)) {
                upstreamIfaceTypes.add(TYPE_MOBILE_HIPRI);
            }
            appendIfNotPresent(upstreamIfaceTypes, TYPE_MOBILE);
            appendIfNotPresent(upstreamIfaceTypes, TYPE_MOBILE_HIPRI);
        } else {
            // Fix upstream interface types for case DUN_UNSPECIFIED.
            // Do not modify if a cellular interface type is already present in the
            // upstream interface types. Add TYPE_MOBILE and TYPE_MOBILE_HIPRI if no
            // cellular interface types are found in the upstream interface types.
            if (!(upstreamIfaceTypes.contains(TYPE_MOBILE_DUN)
                    || upstreamIfaceTypes.contains(TYPE_MOBILE)
                    || upstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI))) {
            if (!(containsOneOf(upstreamIfaceTypes,
                    TYPE_MOBILE_DUN, TYPE_MOBILE, TYPE_MOBILE_HIPRI))) {
                upstreamIfaceTypes.add(TYPE_MOBILE);
                upstreamIfaceTypes.add(TYPE_MOBILE_HIPRI);
            }
        }

        // Always make sure our good friend Ethernet is present.
        // TODO: consider unilaterally forcing this at the front.
        prependIfNotPresent(upstreamIfaceTypes, TYPE_ETHERNET);

        return upstreamIfaceTypes;
    }

@@ -253,4 +251,21 @@ public class TetheringConfiguration {
    private static String[] copy(String[] strarray) {
        return Arrays.copyOf(strarray, strarray.length);
    }

    private static void prependIfNotPresent(ArrayList<Integer> list, int value) {
        if (list.contains(value)) return;
        list.add(0, value);
    }

    private static void appendIfNotPresent(ArrayList<Integer> list, int value) {
        if (list.contains(value)) return;
        list.add(value);
    }

    private static boolean containsOneOf(ArrayList<Integer> list, Integer... values) {
        for (Integer value : values) {
            if (list.contains(value)) return true;
        }
        return false;
    }
}
+60 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.connectivity.tethering;

import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_DUN;
import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
@@ -38,6 +39,8 @@ import android.telephony.TelephonyManager;

import com.android.internal.util.test.BroadcastInterceptingContext;

import java.util.Iterator;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -134,4 +137,61 @@ public class TetheringConfigurationTest {
        assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE));
        assertFalse(cfg.preferredUpstreamIfaceTypes.contains(TYPE_MOBILE_HIPRI));
    }

    @Test
    public void testNoDefinedUpstreamTypesAddsEthernet() {
        when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
                .thenReturn(new int[]{});
        mHasTelephonyManager = false;
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);

        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
        final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
        // The following is because the code always adds some kind of mobile
        // upstream, be it DUN or, in this case where we use DUN_UNSPECIFIED,
        // both vanilla and hipri mobile types.
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_MOBILE, upstreamIterator.next().intValue());
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
        assertFalse(upstreamIterator.hasNext());
    }

    @Test
    public void testDefinedUpstreamTypesSansEthernetAddsEthernet() {
        when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
                .thenReturn(new int[]{TYPE_WIFI, TYPE_MOBILE_HIPRI});
        mHasTelephonyManager = false;
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);

        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
        final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
        assertFalse(upstreamIterator.hasNext());
    }

    @Test
    public void testDefinedUpstreamTypesWithEthernetDoesNotAddEthernet() {
        when(mResources.getIntArray(com.android.internal.R.array.config_tether_upstream_types))
                .thenReturn(new int[]{TYPE_WIFI, TYPE_ETHERNET, TYPE_MOBILE_HIPRI});
        mHasTelephonyManager = false;
        when(mTelephonyManager.getTetherApnRequired()).thenReturn(DUN_UNSPECIFIED);

        final TetheringConfiguration cfg = new TetheringConfiguration(mMockContext, mLog);
        final Iterator<Integer> upstreamIterator = cfg.preferredUpstreamIfaceTypes.iterator();
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_WIFI, upstreamIterator.next().intValue());
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_ETHERNET, upstreamIterator.next().intValue());
        assertTrue(upstreamIterator.hasNext());
        assertEquals(TYPE_MOBILE_HIPRI, upstreamIterator.next().intValue());
        assertFalse(upstreamIterator.hasNext());
    }
}