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

Commit d649c128 authored by Irfan Sheriff's avatar Irfan Sheriff
Browse files

Make NetworkStateTracker an interface

As part of the WifiStateTracker cleanup, need
to have NetworkStateTracker as an interface.

Change-Id: I2ac48d7e4c7274ac4df40bc3b8591b182956a936
parent 051e1945
Loading
Loading
Loading
Loading
+183 −20
Original line number Diff line number Diff line
@@ -22,11 +22,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.RemoteException;
import android.os.Handler;
import android.os.Message;
import android.os.ServiceManager;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.TelephonyIntents;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.text.TextUtils;
@@ -38,7 +40,7 @@ import android.text.TextUtils;
 *
 * {@hide}
 */
public class MobileDataStateTracker extends NetworkStateTracker {
public class MobileDataStateTracker implements NetworkStateTracker {

    private static final String TAG = "MobileDataStateTracker";
    private static final boolean DBG = true;
@@ -48,6 +50,15 @@ public class MobileDataStateTracker extends NetworkStateTracker {

    private String mApnType;
    private BroadcastReceiver mStateReceiver;
    private static String[] sDnsPropNames;
    private NetworkInfo mNetworkInfo;
    private boolean mTeardownRequested = false;
    private Handler mTarget;
    private Context mContext;
    private String mInterfaceName;
    private boolean mPrivateDnsRouteSet = false;
    private int mDefaultGatewayAddr = 0;
    private boolean mDefaultRouteSet = false;

    /**
     * Create a new MobileDataStateTracker
@@ -58,14 +69,16 @@ public class MobileDataStateTracker extends NetworkStateTracker {
     * @param tag the name of this network
     */
    public MobileDataStateTracker(Context context, Handler target, int netType, String tag) {
        super(context, target, netType,
        mTarget = target;
        mContext = context;
        mNetworkInfo = new NetworkInfo(netType,
                TelephonyManager.getDefault().getNetworkType(), tag,
                TelephonyManager.getDefault().getNetworkTypeName());
        mApnType = networkTypeToApnType(netType);

        mPhoneService = null;

        mDnsPropNames = new String[] {
        sDnsPropNames = new String[] {
                "net.rmnet0.dns1",
                "net.rmnet0.dns2",
                "net.eth0.dns1",
@@ -79,6 +92,53 @@ public class MobileDataStateTracker extends NetworkStateTracker {

    }

    /**
     * Return the IP addresses of the DNS servers available for the mobile data
     * network interface.
     * @return a list of DNS addresses, with no holes.
     */
    public String[] getDnsPropNames() {
        return sDnsPropNames;
    }

    /**
     * Return the name of our network interface.
     * @return the name of our interface.
     */
    public String getInterfaceName() {
        return mInterfaceName;
    }

    public boolean isPrivateDnsRouteSet() {
        return mPrivateDnsRouteSet;
    }

    public void privateDnsRouteSet(boolean enabled) {
        mPrivateDnsRouteSet = enabled;
    }

    public NetworkInfo getNetworkInfo() {
        return mNetworkInfo;
    }

    public int getDefaultGatewayAddr() {
        return mDefaultGatewayAddr;
    }

    public boolean isDefaultRouteSet() {
        return mDefaultRouteSet;
    }

    public void defaultRouteSet(boolean enabled) {
        mDefaultRouteSet = enabled;
    }

    /**
     * This is not implemented.
     */
    public void releaseWakeLock() {
    }

    /**
     * Begin monitoring mobile data connectivity.
     */
@@ -93,6 +153,32 @@ public class MobileDataStateTracker extends NetworkStateTracker {
        mMobileDataState = Phone.DataState.DISCONNECTED;
    }

    /**
     * Record the roaming status of the device, and if it is a change from the previous
     * status, send a notification to any listeners.
     * @param isRoaming {@code true} if the device is now roaming, {@code false}
     * if it is no longer roaming.
     */
    private void setRoamingStatus(boolean isRoaming) {
        if (isRoaming != mNetworkInfo.isRoaming()) {
            mNetworkInfo.setRoaming(isRoaming);
            Message msg = mTarget.obtainMessage(EVENT_ROAMING_CHANGED, mNetworkInfo);
            msg.sendToTarget();
        }
    }

    private void setSubtype(int subtype, String subtypeName) {
        if (mNetworkInfo.isConnected()) {
            int oldSubtype = mNetworkInfo.getSubtype();
            if (subtype != oldSubtype) {
                mNetworkInfo.setSubtype(subtype, subtypeName);
                Message msg = mTarget.obtainMessage(
                        EVENT_NETWORK_SUBTYPE_CHANGED, oldSubtype, 0, mNetworkInfo);
                msg.sendToTarget();
            }
        }
    }

    private class MobileDataStateReceiver extends BroadcastReceiver {
        public void onReceive(Context context, Intent intent) {
            synchronized(this) {
@@ -260,12 +346,62 @@ public class MobileDataStateTracker extends NetworkStateTracker {
     * mobile data connections.
     * TODO - make async and return nothing?
     */
    @Override
    public boolean teardown() {
        setTeardownRequested(true);
        return (setEnableApn(mApnType, false) != Phone.APN_REQUEST_FAILED);
    }

    /**
     * Record the detailed state of a network, and if it is a
     * change from the previous state, send a notification to
     * any listeners.
     * @param state the new @{code DetailedState}
     */
    private void setDetailedState(NetworkInfo.DetailedState state) {
        setDetailedState(state, null, null);
    }

    /**
     * Record the detailed state of a network, and if it is a
     * change from the previous state, send a notification to
     * any listeners.
     * @param state the new @{code DetailedState}
     * @param reason a {@code String} indicating a reason for the state change,
     * if one was supplied. May be {@code null}.
     * @param extraInfo optional {@code String} providing extra information about the state change
     */
    private void setDetailedState(NetworkInfo.DetailedState state, String reason, String extraInfo) {
        if (DBG) Log.d(TAG, "setDetailed state, old ="
                + mNetworkInfo.getDetailedState() + " and new state=" + state);
        if (state != mNetworkInfo.getDetailedState()) {
            boolean wasConnecting = (mNetworkInfo.getState() == NetworkInfo.State.CONNECTING);
            String lastReason = mNetworkInfo.getReason();
            /*
             * If a reason was supplied when the CONNECTING state was entered, and no
             * reason was supplied for entering the CONNECTED state, then retain the
             * reason that was supplied when going to CONNECTING.
             */
            if (wasConnecting && state == NetworkInfo.DetailedState.CONNECTED && reason == null
                    && lastReason != null)
                reason = lastReason;
            mNetworkInfo.setDetailedState(state, reason, extraInfo);
            Message msg = mTarget.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
            msg.sendToTarget();
        }
    }

    private void setDetailedStateInternal(NetworkInfo.DetailedState state) {
        mNetworkInfo.setDetailedState(state, null, null);
    }

    public void setTeardownRequested(boolean isRequested) {
        mTeardownRequested = isRequested;
    }

    public boolean isTeardownRequested() {
        return mTeardownRequested;
    }

    /**
     * Re-enable mobile data connectivity after a {@link #teardown()}.
     * TODO - make async and always get a notification?
@@ -322,23 +458,50 @@ public class MobileDataStateTracker extends NetworkStateTracker {
    }

    /**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the mobile data network.
     * @param hostAddress the IP address of the host to which the route is desired,
     * in network byte order.
     * @return {@code true} on success, {@code false} on failure
     * Tells the phone sub-system that the caller wants to
     * begin using the named feature. The only supported features at
     * this time are {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
     * to specify that it wants to send and/or receive MMS data, and
     * {@code Phone.FEATURE_ENABLE_SUPL}, which is used for Assisted GPS.
     * @param feature the name of the feature to be used
     * @param callingPid the process ID of the process that is issuing this request
     * @param callingUid the user ID of the process that is issuing this request
     * @return an integer value representing the outcome of the request.
     * The interpretation of this value is feature-specific.
     * specific, except that the value {@code -1}
     * always indicates failure. For {@code Phone.FEATURE_ENABLE_MMS},
     * the other possible return values are
     * <ul>
     * <li>{@code Phone.APN_ALREADY_ACTIVE}</li>
     * <li>{@code Phone.APN_REQUEST_STARTED}</li>
     * <li>{@code Phone.APN_TYPE_NOT_AVAILABLE}</li>
     * <li>{@code Phone.APN_REQUEST_FAILED}</li>
     * </ul>
     */
    @Override
    public boolean requestRouteToHost(int hostAddress) {
        if (DBG) {
            Log.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress) +
                    " for " + mApnType + "(" + mInterfaceName + ")");
    public int startUsingNetworkFeature(String feature, int callingPid, int callingUid) {
        return -1;
    }
        if (mInterfaceName != null && hostAddress != -1) {
            return NetworkUtils.addHostRoute(mInterfaceName, hostAddress) == 0;
        } else {
            return false;

    /**
     * Tells the phone sub-system that the caller is finished
     * using the named feature. The only supported feature at
     * this time is {@code Phone.FEATURE_ENABLE_MMS}, which allows an application
     * to specify that it wants to send and/or receive MMS data.
     * @param feature the name of the feature that is no longer needed
     * @param callingPid the process ID of the process that is issuing this request
     * @param callingUid the user ID of the process that is issuing this request
     * @return an integer value representing the outcome of the request.
     * The interpretation of this value is feature-specific, except that
     * the value {@code -1} always indicates failure.
     */
    public int stopUsingNetworkFeature(String feature, int callingPid, int callingUid) {
        return -1;
    }

    /**
     * This is not supported.
     */
    public void interpretScanResultsAvailable() {
    }

    @Override
+6 −2
Original line number Diff line number Diff line
@@ -121,7 +121,10 @@ public class NetworkInfo implements Parcelable {
     */
    public NetworkInfo(int type) {}

    NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
    /**
     * @hide
     */
    public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
        if (!ConnectivityManager.isNetworkTypeValid(type)) {
            throw new IllegalArgumentException("Invalid network type: " + type);
        }
@@ -281,8 +284,9 @@ public class NetworkInfo implements Parcelable {
     * if one was supplied. May be {@code null}.
     * @param extraInfo an optional {@code String} providing addditional network state
     * information passed up from the lower networking layers.
     * @hide
     */
    void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
    public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
        this.mDetailedState = detailedState;
        this.mState = stateMap.get(detailedState);
        this.mReason = reason;
+62 −281

File changed.

Preview size limit exceeded, changes collapsed.

+201 −8
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.net.MobileDataStateTracker;
import android.net.NetworkInfo;
import android.net.NetworkStateTracker;
import android.net.wifi.WifiStateTracker;
import android.net.NetworkUtils;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
@@ -46,6 +47,8 @@ import com.android.internal.telephony.Phone;
import com.android.server.connectivity.Tethering;

import java.io.FileDescriptor;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -743,7 +746,32 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            }
            return false;
        }
        return tracker.requestRouteToHost(hostAddress);
        return addHostRoute(tracker, hostAddress);
    }

    /**
     * Ensure that a network route exists to deliver traffic to the specified
     * host via the mobile data network.
     * @param hostAddress the IP address of the host to which the route is desired,
     * in network byte order.
     * @return {@code true} on success, {@code false} on failure
     */
    private boolean addHostRoute(NetworkStateTracker nt, int hostAddress) {
        if (nt.getNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI) {
            return false;
        }

        String interfaceName = nt.getInterfaceName();

        if (DBG) {
            Slog.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress) +
                     "(" + interfaceName + ")");
        }
        if (interfaceName != null && hostAddress != -1) {
            return NetworkUtils.addHostRoute(interfaceName, hostAddress) == 0;
        } else {
            return false;
        }
    }

    /**
@@ -1133,7 +1161,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            mActiveDefaultNetwork = type;
        }
        thisNet.setTeardownRequested(false);
        thisNet.updateNetworkSettings();
        updateNetworkSettings(thisNet);
        handleConnectivityChange();
        sendConnectedBroadcast(info);
    }
@@ -1183,19 +1211,184 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        for (int netType : mPriorityList) {
            if (mNetTrackers[netType].getNetworkInfo().isConnected()) {
                if (mNetAttributes[netType].isDefault()) {
                    mNetTrackers[netType].addDefaultRoute();
                    addDefaultRoute(mNetTrackers[netType]);
                } else {
                    mNetTrackers[netType].addPrivateDnsRoutes();
                    addPrivateDnsRoutes(mNetTrackers[netType]);
                }
            } else {
                if (mNetAttributes[netType].isDefault()) {
                    mNetTrackers[netType].removeDefaultRoute();
                    removeDefaultRoute(mNetTrackers[netType]);
                } else {
                    removePrivateDnsRoutes(mNetTrackers[netType]);
                }
            }
        }
    }

    private void addPrivateDnsRoutes(NetworkStateTracker nt) {
        String interfaceName = nt.getInterfaceName();
        boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();

        if (DBG) {
            Slog.d(TAG, "addPrivateDnsRoutes for " + nt +
                    "(" + interfaceName + ") - mPrivateDnsRouteSet = " + privateDnsRouteSet);
        }
        String[] dnsList = getNameServerList(nt.getDnsPropNames());
        if (interfaceName != null && !privateDnsRouteSet) {
            for (String addrString : dnsList) {
                int addr = NetworkUtils.lookupHost(addrString);
                if (addr != -1 && addr != 0) {
                    if (DBG) Slog.d(TAG, "  adding "+addrString+" ("+addr+")");
                    NetworkUtils.addHostRoute(interfaceName, addr);
                }
            }
            nt.privateDnsRouteSet(true);
        }
    }

    private void removePrivateDnsRoutes(NetworkStateTracker nt) {
        // TODO - we should do this explicitly but the NetUtils api doesnt
        // support this yet - must remove all.  No worse than before
        String interfaceName = nt.getInterfaceName();
        boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet();
        if (interfaceName != null && privateDnsRouteSet) {
            if (DBG) {
                Slog.d(TAG, "removePrivateDnsRoutes for " + nt.getNetworkInfo().getTypeName() +
                        " (" + interfaceName + ")");
            }
            NetworkUtils.removeHostRoutes(interfaceName);
            nt.privateDnsRouteSet(false);
        }
    }

    /**
     * Return the IP addresses of the DNS servers available for this
     * network interface.
     * @param propertyNames the names of the system properties whose values
     * give the IP addresses. Properties with no values are skipped.
     * @return an array of {@code String}s containing the IP addresses
     * of the DNS servers, in dot-notation. This may have fewer
     * non-null entries than the list of names passed in, since
     * some of the passed-in names may have empty values.
     */
    String[] getNameServerList(String[] propertyNames) {
        String[] dnsAddresses = new String[propertyNames.length];
        int i, j;

        for (i = 0, j = 0; i < propertyNames.length; i++) {
            String value = SystemProperties.get(propertyNames[i]);
            // The GSM layer sometimes sets a bogus DNS server address of
            // 0.0.0.0
            if (!TextUtils.isEmpty(value) && !TextUtils.equals(value, "0.0.0.0")) {
                dnsAddresses[j++] = value;
            }
        }
        return dnsAddresses;
    }

    private void addDefaultRoute(NetworkStateTracker nt) {
        String interfaceName = nt.getInterfaceName();
        int defaultGatewayAddr = nt.getDefaultGatewayAddr();
        boolean defaultRouteSet = nt.isDefaultRouteSet();
        NetworkInfo networkInfo = nt.getNetworkInfo();

        if ((interfaceName != null) && (defaultGatewayAddr != 0) &&
                defaultRouteSet == false) {
            if (DBG) {
                Slog.d(TAG, "addDefaultRoute for " + networkInfo.getTypeName() +
                        " (" + interfaceName + "), GatewayAddr=" + defaultGatewayAddr);
            }
            NetworkUtils.setDefaultRoute(interfaceName, defaultGatewayAddr);
            nt.defaultRouteSet(true);
        }
    }


    public void removeDefaultRoute(NetworkStateTracker nt) {
        String interfaceName = nt.getInterfaceName();
        boolean defaultRouteSet = nt.isDefaultRouteSet();
        NetworkInfo networkInfo = nt.getNetworkInfo();

        if (interfaceName != null && defaultRouteSet == true) {
            if (DBG) {
                Slog.d(TAG, "removeDefaultRoute for " + networkInfo.getTypeName() + " (" +
                        interfaceName + ")");
            }
            NetworkUtils.removeDefaultRoute(interfaceName);
            nt.defaultRouteSet(false);
        }
    }

   /**
     * Reads the network specific TCP buffer sizes from SystemProperties
     * net.tcp.buffersize.[default|wifi|umts|edge|gprs] and set them for system
     * wide use
     */
   public void updateNetworkSettings(NetworkStateTracker nt) {
        String key = nt.getTcpBufferSizesPropName();
        String bufferSizes = SystemProperties.get(key);

        if (bufferSizes.length() == 0) {
            Slog.e(TAG, key + " not found in system properties. Using defaults");

            // Setting to default values so we won't be stuck to previous values
            key = "net.tcp.buffersize.default";
            bufferSizes = SystemProperties.get(key);
        }

        // Set values in kernel
        if (bufferSizes.length() != 0) {
            if (DBG) {
                Slog.v(TAG, "Setting TCP values: [" + bufferSizes
                        + "] which comes from [" + key + "]");
            }
            setBufferSize(bufferSizes);
        }
    }

   /**
     * Writes TCP buffer sizes to /sys/kernel/ipv4/tcp_[r/w]mem_[min/def/max]
     * which maps to /proc/sys/net/ipv4/tcp_rmem and tcpwmem
     *
     * @param bufferSizes in the format of "readMin, readInitial, readMax,
     *        writeMin, writeInitial, writeMax"
     */
    private void setBufferSize(String bufferSizes) {
        try {
            String[] values = bufferSizes.split(",");

            if (values.length == 6) {
              final String prefix = "/sys/kernel/ipv4/tcp_";
                stringToFile(prefix + "rmem_min", values[0]);
                stringToFile(prefix + "rmem_def", values[1]);
                stringToFile(prefix + "rmem_max", values[2]);
                stringToFile(prefix + "wmem_min", values[3]);
                stringToFile(prefix + "wmem_def", values[4]);
                stringToFile(prefix + "wmem_max", values[5]);
            } else {
                    mNetTrackers[netType].removePrivateDnsRoutes();
                Slog.e(TAG, "Invalid buffersize string: " + bufferSizes);
            }
        } catch (IOException e) {
            Slog.e(TAG, "Can't set tcp buffer sizes:" + e);
        }
    }

   /**
     * Writes string to file. Basically same as "echo -n $string > $filename"
     *
     * @param filename
     * @param string
     * @throws IOException
     */
    private void stringToFile(String filename, String string) throws IOException {
        FileWriter out = new FileWriter(filename);
        try {
            out.write(string);
        } finally {
            out.close();
        }
    }


    /**
     * Adjust the per-process dns entries (net.dns<x>.<pid>) based
@@ -1216,7 +1409,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
                for (int j=0; j<pids.size(); j++) {
                    Integer pid = (Integer)pids.get(j);
                    if (pid.intValue() == myPid) {
                        String[] dnsList = nt.getNameServers();
                        String[] dnsList = getNameServerList(nt.getDnsPropNames());
                        writePidDns(dnsList, myPid);
                        if (doBump) {
                            bumpDns();
@@ -1270,7 +1463,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
            NetworkStateTracker nt = mNetTrackers[netType];
            if (nt != null && nt.getNetworkInfo().isConnected() &&
                    !nt.isTeardownRequested()) {
                String[] dnsList = nt.getNameServers();
                String[] dnsList = getNameServerList(nt.getDnsPropNames());
                if (mNetAttributes[netType].isDefault()) {
                    int j = 1;
                    for (String dns : dnsList) {
+117 −7

File changed.

Preview size limit exceeded, changes collapsed.