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

Commit a34c9ca3 authored by Kenny Root's avatar Kenny Root Committed by android-build SharedAccount
Browse files

Add more error checking for ndc

In NativeDaemonConnector.doCommand() calls, there was inconsistent error
checking. This change adds error checking for every call and makes it so
that any call to .doCommand() that gets an error code won't cause the
code to hang forever.

Change-Id: If714282b6642f278fb8137f652af1a012670253b
parent 24a03083
Loading
Loading
Loading
Loading
+27 −7
Original line number Original line Diff line number Diff line
@@ -642,10 +642,20 @@ class MountService extends IMountService.Stub
    }
    }


    private boolean doGetShareMethodAvailable(String method) {
    private boolean doGetShareMethodAvailable(String method) {
        try {
            ArrayList<String> rsp = mConnector.doCommand("share status " + method);
            ArrayList<String> rsp = mConnector.doCommand("share status " + method);
        } catch (NativeDaemonConnectorException ex) {
            Slog.e(TAG, "Failed to determine whether share method " + method + " is available.");
            return false;
        }


        for (String line : rsp) {
        for (String line : rsp) {
            String[] tok = line.split(" ");
            String[] tok = line.split(" ");
            if (tok.length < 3) {
                Slog.e(TAG, "Malformed response to share status " + method);
                return false;
            }

            int code;
            int code;
            try {
            try {
                code = Integer.parseInt(tok[0]);
                code = Integer.parseInt(tok[0]);
@@ -770,10 +780,22 @@ class MountService extends IMountService.Stub


    private boolean doGetVolumeShared(String path, String method) {
    private boolean doGetVolumeShared(String path, String method) {
        String cmd = String.format("volume shared %s %s", path, method);
        String cmd = String.format("volume shared %s %s", path, method);
        ArrayList<String> rsp = mConnector.doCommand(cmd);
        ArrayList<String> rsp;

        try {
            rsp = mConnector.doCommand(cmd);
        } catch (NativeDaemonConnectorException ex) {
            Slog.e(TAG, "Failed to read response to volume shared " + path + " " + method);
            return false;
        }


        for (String line : rsp) {
        for (String line : rsp) {
            String[] tok = line.split(" ");
            String[] tok = line.split(" ");
            if (tok.length < 3) {
                Slog.e(TAG, "Malformed response to volume shared " + path + " " + method + " command");
                return false;
            }

            int code;
            int code;
            try {
            try {
                code = Integer.parseInt(tok[0]);
                code = Integer.parseInt(tok[0]);
@@ -782,9 +804,7 @@ class MountService extends IMountService.Stub
                return false;
                return false;
            }
            }
            if (code == VoldResponseCode.ShareEnabledResult) {
            if (code == VoldResponseCode.ShareEnabledResult) {
                if (tok[2].equals("enabled"))
                return "enabled".equals(tok[2]);
                    return true;
                return false;
            } else {
            } else {
                Slog.e(TAG, String.format("Unexpected response code %d", code));
                Slog.e(TAG, String.format("Unexpected response code %d", code));
                return false;
                return false;
+5 −6
Original line number Original line Diff line number Diff line
@@ -128,13 +128,12 @@ final class NativeDaemonConnector implements Runnable {
                                    Slog.e(TAG, String.format(
                                    Slog.e(TAG, String.format(
                                            "Error handling '%s'", event), ex);
                                            "Error handling '%s'", event), ex);
                                }
                                }
                            } else {
                            }
                            try {
                            try {
                                mResponseQueue.put(event);
                                mResponseQueue.put(event);
                            } catch (InterruptedException ex) {
                            } catch (InterruptedException ex) {
                                Slog.e(TAG, "Failed to put response onto queue", ex);
                                Slog.e(TAG, "Failed to put response onto queue", ex);
                            }
                            }
                            }
                        } catch (NumberFormatException nfe) {
                        } catch (NumberFormatException nfe) {
                            Slog.w(TAG, String.format("Bad msg (%s)", event));
                            Slog.w(TAG, String.format("Bad msg (%s)", event));
                        }
                        }
+248 −100
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.StringTokenizer;
import android.provider.Settings;
import android.provider.Settings;
import android.content.ContentResolver;
import android.content.ContentResolver;
@@ -226,16 +227,29 @@ class NetworkManagementService extends INetworkManagementService.Stub {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");


        try {
            return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult);
            return mConnector.doListCommand("interface list", NetdResponseCode.InterfaceListResult);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Cannot communicate with native daemon to list interfaces");
        }
    }
    }


    public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException {
    public InterfaceConfiguration getInterfaceConfig(String iface) throws IllegalStateException {
        String rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
        String rsp;
        try {
            rsp = mConnector.doCommand("interface getcfg " + iface).get(0);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Cannot communicate with native daemon to get interface config");
        }
        Slog.d(TAG, String.format("rsp <%s>", rsp));
        Slog.d(TAG, String.format("rsp <%s>", rsp));


        // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3]
        // Rsp: 213 xx:xx:xx:xx:xx:xx yyy.yyy.yyy.yyy zzz.zzz.zzz.zzz [flag1 flag2 flag3]
        StringTokenizer st = new StringTokenizer(rsp);
        StringTokenizer st = new StringTokenizer(rsp);


        InterfaceConfiguration cfg;
        try {
            try {
            try {
                int code = Integer.parseInt(st.nextToken(" "));
                int code = Integer.parseInt(st.nextToken(" "));
                if (code != NetdResponseCode.InterfaceGetCfgResult) {
                if (code != NetdResponseCode.InterfaceGetCfgResult) {
@@ -248,7 +262,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                        String.format("Invalid response from daemon (%s)", rsp));
                        String.format("Invalid response from daemon (%s)", rsp));
            }
            }


        InterfaceConfiguration cfg = new InterfaceConfiguration();
            cfg = new InterfaceConfiguration();
            cfg.hwAddr = st.nextToken(" ");
            cfg.hwAddr = st.nextToken(" ");
            try {
            try {
                cfg.ipAddr = stringToIpAddr(st.nextToken(" "));
                cfg.ipAddr = stringToIpAddr(st.nextToken(" "));
@@ -264,6 +278,10 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                cfg.netmask = 0;
                cfg.netmask = 0;
            }
            }
            cfg.interfaceFlags = st.nextToken("]").trim() +"]";
            cfg.interfaceFlags = st.nextToken("]").trim() +"]";
        } catch (NoSuchElementException nsee) {
            throw new IllegalStateException(
                    String.format("Invalid response from daemon (%s)", rsp));
        }
        Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags));
        Slog.d(TAG, String.format("flags <%s>", cfg.interfaceFlags));
        return cfg;
        return cfg;
    }
    }
@@ -272,7 +290,12 @@ class NetworkManagementService extends INetworkManagementService.Stub {
            String iface, InterfaceConfiguration cfg) throws IllegalStateException {
            String iface, InterfaceConfiguration cfg) throws IllegalStateException {
        String cmd = String.format("interface setcfg %s %s %s %s", iface,
        String cmd = String.format("interface setcfg %s %s %s %s", iface,
                intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags);
                intToIpString(cfg.ipAddr), intToIpString(cfg.netmask), cfg.interfaceFlags);
        try {
            mConnector.doCommand(cmd);
            mConnector.doCommand(cmd);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate with native daemon to interface setcfg");
        }
    }
    }


    public void shutdown() {
    public void shutdown() {
@@ -289,20 +312,25 @@ class NetworkManagementService extends INetworkManagementService.Stub {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");


        ArrayList<String> rsp = mConnector.doCommand("ipfwd status");
        ArrayList<String> rsp;
        try {
            rsp = mConnector.doCommand("ipfwd status");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate with native daemon to ipfwd status");
        }


        for (String line : rsp) {
        for (String line : rsp) {
            String[] tok = line.split(" ");
            String[] tok = line.split(" ");
            if (tok.length < 3) {
                Slog.e(TAG, "Malformed response from native daemon: " + line);
                return false;
            }

            int code = Integer.parseInt(tok[0]);
            int code = Integer.parseInt(tok[0]);
            if (code == NetdResponseCode.IpFwdStatusResult) {
            if (code == NetdResponseCode.IpFwdStatusResult) {
                // 211 Forwarding <enabled/disabled>
                // 211 Forwarding <enabled/disabled>
                if (tok.length !=2) {
                return "enabled".equals(tok[2]);
                    throw new IllegalStateException(
                            String.format("Malformatted list entry '%s'", line));
                }
                if (tok[2].equals("enabled"))
                    return true;
                return false;
            } else {
            } else {
                throw new IllegalStateException(String.format("Unexpected response code %d", code));
                throw new IllegalStateException(String.format("Unexpected response code %d", code));
            }
            }
@@ -326,29 +354,45 @@ class NetworkManagementService extends INetworkManagementService.Stub {
        for (String d : dhcpRange) {
        for (String d : dhcpRange) {
            cmd += " " + d;
            cmd += " " + d;
        }
        }

        try {
            mConnector.doCommand(cmd);
            mConnector.doCommand(cmd);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Unable to communicate to native daemon");
        }
    }
    }


    public void stopTethering() throws IllegalStateException {
    public void stopTethering() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("tether stop");
            mConnector.doCommand("tether stop");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Unable to communicate to native daemon to stop tether");
        }
    }
    }


    public boolean isTetheringStarted() throws IllegalStateException {
    public boolean isTetheringStarted() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");


        ArrayList<String> rsp = mConnector.doCommand("tether status");
        ArrayList<String> rsp;
        try {
            rsp = mConnector.doCommand("tether status");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon to get tether status");
        }


        for (String line : rsp) {
        for (String line : rsp) {
            String[] tok = line.split(" ");
            String[] tok = line.split(" ");
            if (tok.length < 3) {
                throw new IllegalStateException("Malformed response for tether status: " + line);
            }
            int code = Integer.parseInt(tok[0]);
            int code = Integer.parseInt(tok[0]);
            if (code == NetdResponseCode.TetherStatusResult) {
            if (code == NetdResponseCode.TetherStatusResult) {
                // XXX: Tethering services <started/stopped> <TBD>...
                // XXX: Tethering services <started/stopped> <TBD>...
                if (tok[2].equals("started"))
                return "started".equals(tok[2]);
                    return true;
                return false;
            } else {
            } else {
                throw new IllegalStateException(String.format("Unexpected response code %d", code));
                throw new IllegalStateException(String.format("Unexpected response code %d", code));
            }
            }
@@ -359,20 +403,35 @@ class NetworkManagementService extends INetworkManagementService.Stub {
    public void tetherInterface(String iface) throws IllegalStateException {
    public void tetherInterface(String iface) throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("tether interface add " + iface);
            mConnector.doCommand("tether interface add " + iface);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for adding tether interface");
        }
    }
    }


    public void untetherInterface(String iface) {
    public void untetherInterface(String iface) {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("tether interface remove " + iface);
            mConnector.doCommand("tether interface remove " + iface);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for removing tether interface");
        }
    }
    }


    public String[] listTetheredInterfaces() throws IllegalStateException {
    public String[] listTetheredInterfaces() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        try {
            return mConnector.doListCommand(
            return mConnector.doListCommand(
                    "tether interface list", NetdResponseCode.TetherInterfaceListResult);
                    "tether interface list", NetdResponseCode.TetherInterfaceListResult);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for listing tether interfaces");
        }
    }
    }


    public void setDnsForwarders(String[] dns) throws IllegalStateException {
    public void setDnsForwarders(String[] dns) throws IllegalStateException {
@@ -383,7 +442,12 @@ class NetworkManagementService extends INetworkManagementService.Stub {
            for (String s : dns) {
            for (String s : dns) {
                cmd += " " + InetAddress.getByName(s).getHostAddress();
                cmd += " " + InetAddress.getByName(s).getHostAddress();
            }
            }
            try {
                mConnector.doCommand(cmd);
                mConnector.doCommand(cmd);
            } catch (NativeDaemonConnectorException e) {
                throw new IllegalStateException(
                        "Unable to communicate to native daemon for setting tether dns");
            }
        } catch (UnknownHostException e) {
        } catch (UnknownHostException e) {
            throw new IllegalStateException("Error resolving dns name", e);
            throw new IllegalStateException("Error resolving dns name", e);
        }
        }
@@ -392,30 +456,50 @@ class NetworkManagementService extends INetworkManagementService.Stub {
    public String[] getDnsForwarders() throws IllegalStateException {
    public String[] getDnsForwarders() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        try {
            return mConnector.doListCommand(
            return mConnector.doListCommand(
                    "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
                    "tether dns list", NetdResponseCode.TetherDnsFwdTgtListResult);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for listing tether dns");
        }
    }
    }


    public void enableNat(String internalInterface, String externalInterface)
    public void enableNat(String internalInterface, String externalInterface)
            throws IllegalStateException {
            throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand(
            mConnector.doCommand(
                    String.format("nat enable %s %s", internalInterface, externalInterface));
                    String.format("nat enable %s %s", internalInterface, externalInterface));
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for enabling NAT interface");
        }
    }
    }


    public void disableNat(String internalInterface, String externalInterface)
    public void disableNat(String internalInterface, String externalInterface)
            throws IllegalStateException {
            throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand(
            mConnector.doCommand(
                    String.format("nat disable %s %s", internalInterface, externalInterface));
                    String.format("nat disable %s %s", internalInterface, externalInterface));
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for disabling NAT interface");
        }
    }
    }


    public String[] listTtys() throws IllegalStateException {
    public String[] listTtys() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        try {
            return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
            return mConnector.doListCommand("list_ttys", NetdResponseCode.TtyListResult);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Unable to communicate to native daemon for listing TTYs");
        }
    }
    }


    public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr,
    public void attachPppd(String tty, String localAddr, String remoteAddr, String dns1Addr,
@@ -430,31 +514,52 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                    InetAddress.getByName(dns2Addr).getHostAddress()));
                    InetAddress.getByName(dns2Addr).getHostAddress()));
        } catch (UnknownHostException e) {
        } catch (UnknownHostException e) {
            throw new IllegalStateException("Error resolving addr", e);
            throw new IllegalStateException("Error resolving addr", e);
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon to attach pppd", e);
        }
        }
    }
    }


    public void detachPppd(String tty) throws IllegalStateException {
    public void detachPppd(String tty) throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand(String.format("pppd detach %s", tty));
            mConnector.doCommand(String.format("pppd detach %s", tty));
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon to detach pppd", e);
        }
    }
    }


    public void startUsbRNDIS() throws IllegalStateException {
    public void startUsbRNDIS() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("usb startrndis");
            mConnector.doCommand("usb startrndis");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Error communicating to native daemon for starting RNDIS", e);
        }
    }
    }


    public void stopUsbRNDIS() throws IllegalStateException {
    public void stopUsbRNDIS() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("usb stoprndis");
            mConnector.doCommand("usb stoprndis");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon", e);
        }
    }
    }


    public boolean isUsbRNDISStarted() throws IllegalStateException {
    public boolean isUsbRNDISStarted() throws IllegalStateException {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        ArrayList<String> rsp = mConnector.doCommand("usb rndisstatus");
        ArrayList<String> rsp;
        try {
            rsp = mConnector.doCommand("usb rndisstatus");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException(
                    "Error communicating to native daemon to check RNDIS status", e);
        }


        for (String line : rsp) {
        for (String line : rsp) {
            String []tok = line.split(" ");
            String []tok = line.split(" ");
@@ -476,6 +581,7 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand(String.format("softap stop " + wlanIface));
            mConnector.doCommand(String.format("softap stop " + wlanIface));
            mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
            mConnector.doCommand(String.format("softap fwreload " + wlanIface + " AP"));
            mConnector.doCommand(String.format("softap start " + wlanIface));
            mConnector.doCommand(String.format("softap start " + wlanIface));
@@ -501,6 +607,9 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                mConnector.doCommand(str);
                mConnector.doCommand(str);
            }
            }
            mConnector.doCommand(String.format("softap startap"));
            mConnector.doCommand(String.format("softap startap"));
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon to start softap", e);
        }
    }
    }


    private String convertQuotedString(String s) {
    private String convertQuotedString(String s) {
@@ -516,7 +625,12 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand("softap stopap");
            mConnector.doCommand("softap stopap");
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon to stop soft AP",
                    e);
        }
    }
    }


    public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface)
    public void setAccessPoint(WifiConfiguration wifiConfig, String wlanIface, String softapIface)
@@ -525,25 +639,42 @@ class NetworkManagementService extends INetworkManagementService.Stub {
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
            android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
            android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
        try {
            if (wifiConfig == null) {
            if (wifiConfig == null) {
                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
                mConnector.doCommand(String.format("softap set " + wlanIface + " " + softapIface));
            } else {
            } else {
            String str = String.format("softap set " + wlanIface + " " + softapIface +
                String str = String.format("softap set " + wlanIface + " " + softapIface
                                       " %s %s %s", convertQuotedString(wifiConfig.SSID),
                        + " %s %s %s", convertQuotedString(wifiConfig.SSID),
                                       wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
                        wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ? "wpa2-psk" : "open",
                                       "wpa2-psk" : "open",
                        convertQuotedString(wifiConfig.preSharedKey));
                        convertQuotedString(wifiConfig.preSharedKey));
                mConnector.doCommand(str);
                mConnector.doCommand(str);
            }
            }
        } catch (NativeDaemonConnectorException e) {
            throw new IllegalStateException("Error communicating to native daemon to set soft AP",
                    e);
        }
    }
    }


    private long getInterfaceCounter(String iface, boolean rx) {
    private long getInterfaceCounter(String iface, boolean rx) {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        try {
        try {
            String rsp = mConnector.doCommand(
            String rsp;
            try {
                rsp = mConnector.doCommand(
                        String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
                        String.format("interface read%scounter %s", (rx ? "rx" : "tx"), iface)).get(0);
            } catch (NativeDaemonConnectorException e1) {
                Slog.e(TAG, "Error communicating with native daemon", e1);
                return -1;
            }

            String[] tok = rsp.split(" ");
            String[] tok = rsp.split(" ");
            if (tok.length < 2) {
                Slog.e(TAG, String.format("Malformed response for reading %s interface",
                        (rx ? "rx" : "tx")));
                return -1;
            }

            int code;
            int code;
            try {
            try {
                code = Integer.parseInt(tok[0]);
                code = Integer.parseInt(tok[0]);
@@ -575,17 +706,34 @@ class NetworkManagementService extends INetworkManagementService.Stub {
    public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
    public void setInterfaceThrottle(String iface, int rxKbps, int txKbps) {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
        try {
            mConnector.doCommand(String.format(
            mConnector.doCommand(String.format(
                    "interface setthrottle %s %d %d", iface, rxKbps, txKbps));
                    "interface setthrottle %s %d %d", iface, rxKbps, txKbps));
        } catch (NativeDaemonConnectorException e) {
            Slog.e(TAG, "Error communicating with native daemon to set throttle", e);
        }
    }
    }


    private int getInterfaceThrottle(String iface, boolean rx) {
    private int getInterfaceThrottle(String iface, boolean rx) {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
                android.Manifest.permission.ACCESS_NETWORK_STATE, "NetworkManagementService");
        try {
        try {
            String rsp = mConnector.doCommand(
            String rsp;
                    String.format("interface getthrottle %s %s", iface,(rx ? "rx" : "tx"))).get(0);
            try {
                rsp = mConnector.doCommand(
                        String.format("interface getthrottle %s %s", iface,
                                (rx ? "rx" : "tx"))).get(0);
            } catch (NativeDaemonConnectorException e) {
                Slog.e(TAG, "Error communicating with native daemon to getthrottle", e);
                return -1;
            }

            String[] tok = rsp.split(" ");
            String[] tok = rsp.split(" ");
            if (tok.length < 2) {
                Slog.e(TAG, "Malformed response to getthrottle command");
                return -1;
            }

            int code;
            int code;
            try {
            try {
                code = Integer.parseInt(tok[0]);
                code = Integer.parseInt(tok[0]);