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

Commit c313123a authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add ConnectivityManager.networkCapabilitiesForType()"

parents 05550d9e 35bf06c9
Loading
Loading
Loading
Loading
+74 −29
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import android.telephony.SubscriptionManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;

import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.PhoneConstants;
@@ -1219,36 +1220,27 @@ public class ConnectivityManager {

    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
        if (networkType == TYPE_MOBILE) {
            int cap = -1;
            if ("enableMMS".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_MMS;
            } else if ("enableSUPL".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
            } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_DUN;
            } else if ("enableHIPRI".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
            } else if ("enableFOTA".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
            } else if ("enableIMS".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_IMS;
            } else if ("enableCBS".equals(feature)) {
                cap = NetworkCapabilities.NET_CAPABILITY_CBS;
            } else {
            switch (feature) {
                case "enableCBS":
                    return networkCapabilitiesForType(TYPE_MOBILE_CBS);
                case "enableDUN":
                case "enableDUNAlways":
                    return networkCapabilitiesForType(TYPE_MOBILE_DUN);
                case "enableFOTA":
                    return networkCapabilitiesForType(TYPE_MOBILE_FOTA);
                case "enableHIPRI":
                    return networkCapabilitiesForType(TYPE_MOBILE_HIPRI);
                case "enableIMS":
                    return networkCapabilitiesForType(TYPE_MOBILE_IMS);
                case "enableMMS":
                    return networkCapabilitiesForType(TYPE_MOBILE_MMS);
                case "enableSUPL":
                    return networkCapabilitiesForType(TYPE_MOBILE_SUPL);
                default:
                    return null;
            }
            NetworkCapabilities netCap = new NetworkCapabilities();
            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
            netCap.maybeMarkCapabilitiesRestricted();
            return netCap;
        } else if (networkType == TYPE_WIFI) {
            if ("p2p".equals(feature)) {
                NetworkCapabilities netCap = new NetworkCapabilities();
                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
                netCap.maybeMarkCapabilitiesRestricted();
                return netCap;
            }
        } else if (networkType == TYPE_WIFI && "p2p".equals(feature)) {
            return networkCapabilitiesForType(TYPE_WIFI_P2P);
        }
        return null;
    }
@@ -1456,6 +1448,59 @@ public class ConnectivityManager {
        return true;
    }

    private static final SparseIntArray sLegacyTypeToTransport = new SparseIntArray();
    static {
        sLegacyTypeToTransport.put(TYPE_MOBILE,       NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_CBS,   NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_DUN,   NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_FOTA,  NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_HIPRI, NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_IMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_MMS,   NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_MOBILE_SUPL,  NetworkCapabilities.TRANSPORT_CELLULAR);
        sLegacyTypeToTransport.put(TYPE_WIFI,         NetworkCapabilities.TRANSPORT_WIFI);
        sLegacyTypeToTransport.put(TYPE_WIFI_P2P,     NetworkCapabilities.TRANSPORT_WIFI);
        sLegacyTypeToTransport.put(TYPE_BLUETOOTH,    NetworkCapabilities.TRANSPORT_BLUETOOTH);
        sLegacyTypeToTransport.put(TYPE_ETHERNET,     NetworkCapabilities.TRANSPORT_ETHERNET);
    }

    private static final SparseIntArray sLegacyTypeToCapability = new SparseIntArray();
    static {
        sLegacyTypeToCapability.put(TYPE_MOBILE_CBS,  NetworkCapabilities.NET_CAPABILITY_CBS);
        sLegacyTypeToCapability.put(TYPE_MOBILE_DUN,  NetworkCapabilities.NET_CAPABILITY_DUN);
        sLegacyTypeToCapability.put(TYPE_MOBILE_FOTA, NetworkCapabilities.NET_CAPABILITY_FOTA);
        sLegacyTypeToCapability.put(TYPE_MOBILE_IMS,  NetworkCapabilities.NET_CAPABILITY_IMS);
        sLegacyTypeToCapability.put(TYPE_MOBILE_MMS,  NetworkCapabilities.NET_CAPABILITY_MMS);
        sLegacyTypeToCapability.put(TYPE_MOBILE_SUPL, NetworkCapabilities.NET_CAPABILITY_SUPL);
        sLegacyTypeToCapability.put(TYPE_WIFI_P2P,    NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
    }

    /**
     * Given a legacy type (TYPE_WIFI, ...) returns a NetworkCapabilities
     * instance suitable for registering a request or callback.  Throws an
     * IllegalArgumentException if no mapping from the legacy type to
     * NetworkCapabilities is known.
     *
     * @hide
     */
    public static NetworkCapabilities networkCapabilitiesForType(int type) {
        final NetworkCapabilities nc = new NetworkCapabilities();

        // Map from type to transports.
        final int NOT_FOUND = -1;
        final int transport = sLegacyTypeToTransport.get(type, NOT_FOUND);
        if (transport == NOT_FOUND) {
            throw new IllegalArgumentException("unknown legacy type: " + type);
        }
        nc.addTransportType(transport);

        // Map from type to capabilities.
        nc.addCapability(sLegacyTypeToCapability.get(
                type, NetworkCapabilities.NET_CAPABILITY_INTERNET));
        nc.maybeMarkCapabilitiesRestricted();
        return nc;
    }

    /** @hide */
    public static class PacketKeepaliveCallback {
        /** The requested keepalive was successfully started. */
+14 −0
Original line number Diff line number Diff line
@@ -177,6 +177,20 @@ public class NetworkRequest implements Parcelable {
            return this;
        }

        /**
         * Set the {@code NetworkCapabilities} for this builder instance,
         * overriding any capabilities that had been previously set.
         *
         * @param nc The superseding {@code NetworkCapabilities} instance.
         * @return The builder to facilitate chaining.
         * @hide
         */
        public Builder setCapabilities(NetworkCapabilities nc) {
            mNetworkCapabilities.clearAll();
            mNetworkCapabilities.combineCapabilities(nc);
            return this;
        }

        /**
         * Completely clears all the {@code NetworkCapabilities} from this builder instance,
         * removing even the capabilities that are set by default when the object is constructed.
+28 −32
Original line number Diff line number Diff line
@@ -66,9 +66,9 @@ public class UpstreamNetworkMonitor {
    public static final int EVENT_ON_LINKPROPERTIES = 3;
    public static final int EVENT_ON_LOST           = 4;

    private static final int LISTEN_ALL = 1;
    private static final int TRACK_DEFAULT = 2;
    private static final int MOBILE_REQUEST = 3;
    private static final int CALLBACK_LISTEN_ALL = 1;
    private static final int CALLBACK_TRACK_DEFAULT = 2;
    private static final int CALLBACK_MOBILE_REQUEST = 3;

    private final Context mContext;
    private final StateMachine mTarget;
@@ -98,10 +98,10 @@ public class UpstreamNetworkMonitor {

        final NetworkRequest listenAllRequest = new NetworkRequest.Builder()
                .clearCapabilities().build();
        mListenAllCallback = new UpstreamNetworkCallback(LISTEN_ALL);
        mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL);
        cm().registerNetworkCallback(listenAllRequest, mListenAllCallback);

        mDefaultNetworkCallback = new UpstreamNetworkCallback(TRACK_DEFAULT);
        mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_TRACK_DEFAULT);
        cm().registerDefaultNetworkCallback(mDefaultNetworkCallback);
    }

@@ -136,30 +136,25 @@ public class UpstreamNetworkMonitor {
            return;
        }

        final NetworkRequest.Builder builder = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        if (mDunRequired) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                   .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
        } else {
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        }
        final NetworkRequest mobileUpstreamRequest = builder.build();
        // The following use of the legacy type system cannot be removed until
        // after upstream selection no longer finds networks by legacy type.
        // See also http://b/34364553 .
        final int legacyType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;

        final NetworkRequest mobileUpstreamRequest = new NetworkRequest.Builder()
                .setCapabilities(ConnectivityManager.networkCapabilitiesForType(legacyType))
                .build();

        // The existing default network and DUN callbacks will be notified.
        // Therefore, to avoid duplicate notifications, we only register a no-op.
        mMobileNetworkCallback = new UpstreamNetworkCallback(MOBILE_REQUEST);
        mMobileNetworkCallback = new UpstreamNetworkCallback(CALLBACK_MOBILE_REQUEST);

        // TODO: Change the timeout from 0 (no onUnavailable callback) to some
        // moderate callback timeout. This might be useful for updating some UI.
        // Additionally, we log a message to aid in any subsequent debugging.
        Log.d(TAG, "requesting mobile upstream network: " + mobileUpstreamRequest);

        // The following use of the legacy type system cannot be removed until
        // after upstream selection no longer finds networks by legacy type.
        // See also b/34364553.
        final int apnType = mDunRequired ? TYPE_MOBILE_DUN : TYPE_MOBILE_HIPRI;
        cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, apnType);
        cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType);
    }

    public void releaseMobileNetworkRequest() {
@@ -184,17 +179,18 @@ public class UpstreamNetworkMonitor {
        // Always request whatever extra information we can, in case this
        // was already up when start() was called, in which case we would
        // not have been notified of any information that had not changed.
        final NetworkCallback cb =
                (callbackType == TRACK_DEFAULT) ? mDefaultNetworkCallback :
                (callbackType == MOBILE_REQUEST) ? mMobileNetworkCallback : null;
        if (cb != null) {
            final ConnectivityManager cm = cm();
            cm.requestNetworkCapabilities(mDefaultNetworkCallback);
            cm.requestLinkProperties(mDefaultNetworkCallback);
        }

        if (callbackType == TRACK_DEFAULT) {
        switch (callbackType) {
            case CALLBACK_LISTEN_ALL:
                break;
            case CALLBACK_TRACK_DEFAULT:
                cm().requestNetworkCapabilities(mDefaultNetworkCallback);
                cm().requestLinkProperties(mDefaultNetworkCallback);
                mCurrentDefault = network;
                break;
            case CALLBACK_MOBILE_REQUEST:
                cm().requestNetworkCapabilities(mMobileNetworkCallback);
                cm().requestLinkProperties(mMobileNetworkCallback);
                break;
        }

        // Requesting updates for mListenAllCallback is not currently possible
@@ -262,7 +258,7 @@ public class UpstreamNetworkMonitor {
    }

    private void handleLost(int callbackType, Network network) {
        if (callbackType == TRACK_DEFAULT) {
        if (callbackType == CALLBACK_TRACK_DEFAULT) {
            mCurrentDefault = null;
            // Receiving onLost() for a default network does not necessarily
            // mean the network is gone.  We wait for a separate notification
+176 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOTA;
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_MMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_SUPL;
import static android.net.NetworkCapabilities.NET_CAPABILITY_TRUSTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_WIFI_P2P;
import static android.net.NetworkCapabilities.TRANSPORT_BLUETOOTH;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;

import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.runner.RunWith;
import org.junit.Test;



@RunWith(AndroidJUnit4.class)
@SmallTest
public class ConnectivityManagerTest {
    static NetworkCapabilities verifyNetworkCapabilities(
            int legacyType, int transportType, int... capabilities) {
        final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
        assertNotNull(nc);
        assertTrue(nc.hasTransport(transportType));
        for (int capability : capabilities) {
            assertTrue(nc.hasCapability(capability));
        }

        return nc;
    }

    static void verifyUnrestrictedNetworkCapabilities(int legacyType, int transportType) {
        verifyNetworkCapabilities(
                legacyType,
                transportType,
                NET_CAPABILITY_INTERNET,
                NET_CAPABILITY_NOT_RESTRICTED,
                NET_CAPABILITY_NOT_VPN,
                NET_CAPABILITY_TRUSTED);
    }

    static void verifyRestrictedMobileNetworkCapabilities(int legacyType, int capability) {
        final NetworkCapabilities nc = verifyNetworkCapabilities(
                legacyType,
                TRANSPORT_CELLULAR,
                capability,
                NET_CAPABILITY_NOT_VPN,
                NET_CAPABILITY_TRUSTED);

        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
        assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobile() {
        verifyUnrestrictedNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE, TRANSPORT_CELLULAR);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileCbs() {
        verifyRestrictedMobileNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_CBS, NET_CAPABILITY_CBS);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileDun() {
        verifyRestrictedMobileNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_DUN, NET_CAPABILITY_DUN);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileFota() {
        verifyRestrictedMobileNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_FOTA, NET_CAPABILITY_FOTA);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileHipri() {
        verifyUnrestrictedNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_HIPRI, TRANSPORT_CELLULAR);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileIms() {
        verifyRestrictedMobileNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_IMS, NET_CAPABILITY_IMS);
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileMms() {
        final NetworkCapabilities nc = verifyNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_MMS,
                TRANSPORT_CELLULAR,
                NET_CAPABILITY_MMS,
                NET_CAPABILITY_NOT_VPN,
                NET_CAPABILITY_TRUSTED);

        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
    }

    @Test
    public void testNetworkCapabilitiesForTypeMobileSupl() {
        final NetworkCapabilities nc = verifyNetworkCapabilities(
                ConnectivityManager.TYPE_MOBILE_SUPL,
                TRANSPORT_CELLULAR,
                NET_CAPABILITY_SUPL,
                NET_CAPABILITY_NOT_VPN,
                NET_CAPABILITY_TRUSTED);

        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
    }

    @Test
    public void testNetworkCapabilitiesForTypeWifi() {
        verifyUnrestrictedNetworkCapabilities(
                ConnectivityManager.TYPE_WIFI, TRANSPORT_WIFI);
    }

    @Test
    public void testNetworkCapabilitiesForTypeWifiP2p() {
        final NetworkCapabilities nc = verifyNetworkCapabilities(
                ConnectivityManager.TYPE_WIFI_P2P,
                TRANSPORT_WIFI,
                NET_CAPABILITY_NOT_RESTRICTED, NET_CAPABILITY_NOT_VPN,
                NET_CAPABILITY_TRUSTED, NET_CAPABILITY_WIFI_P2P);

        assertFalse(nc.hasCapability(NET_CAPABILITY_INTERNET));
    }

    @Test
    public void testNetworkCapabilitiesForTypeBluetooth() {
        verifyUnrestrictedNetworkCapabilities(
                ConnectivityManager.TYPE_BLUETOOTH, TRANSPORT_BLUETOOTH);
    }

    @Test
    public void testNetworkCapabilitiesForTypeEthernet() {
        verifyUnrestrictedNetworkCapabilities(
                ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET);
    }
}