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

Commit c9d5fb7c authored by Robert Greenwalt's avatar Robert Greenwalt
Browse files

Add build options for tethering.

Dun-required bool and list of allowed upstream ifaces.
parent 8f7f35e0
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -83,9 +83,17 @@
    </string-array>

    <!-- Dhcp range (min, max) to use for tethering purposes -->
    <string-array name="config_tether_dhcp_range">
    <string-array translatable="false" name="config_tether_dhcp_range">
    </string-array>

    <!-- Regex array of allowable upstream ifaces for tethering - for example if you want
         tethering on your a new interface called "foo2" add "foo\\d" here -->
    <string-array translatable="false" name="config_tether_upstream_regexs">
    </string-array>

    <!-- Boolean indicating if we require the use of DUN on mobile for tethering -->
    <bool translatable="false" name="config_tether_dun_required">true</bool>

    <!-- Flag indicating whether the keyguard should be bypassed when
         the slider is open.  This can be set or unset depending how easily
         the slider can be opened (for example, in a pocket or purse). -->
+10 −3
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {


    private Tethering mTethering;
    private boolean mTetheringConfigValid = false;

    /**
     * Sometimes we want to refer to the individual network state
@@ -320,6 +321,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
        }

        mTethering = new Tethering(mContext);
        mTetheringConfigValid = (((mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null) ||
                                  !mTethering.isDunRequired()) &&
                                 (mTethering.getTetherableUsbRegexs().length != 0 ||
                                  mTethering.getTetherableWifiRegexs().length != 0) &&
                                 mTethering.getUpstreamIfaceRegexs().length != 0);

    }


@@ -1498,8 +1505,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
    public boolean isTetheringSupported() {
        enforceTetherAccessPermission();
        int defaultVal = (SystemProperties.get("ro.tether.denied").equals("true") ? 0 : 1);
        return ((Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0) &&
                (mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null));
        boolean tetherEnabledInSettings = (Settings.Secure.getInt(mContext.getContentResolver(),
                Settings.Secure.TETHER_SUPPORTED, defaultVal) != 0);
        return tetherEnabledInSettings && mTetheringConfigValid;
    }
}
+126 −121
Original line number Diff line number Diff line
@@ -66,10 +66,14 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    private final String TAG = "Tethering";

    private boolean mPlaySounds = false;
    private boolean mBooted = false;
    //used to remember if we got connected before boot finished
    private boolean mDeferedUsbConnection = false;

    // TODO - remove both of these - should be part of interface inspection/selection stuff
    private String[] mTetherableUsbRegexs;
    private String[] mTetherableWifiRegexs;
    private String[] mUpstreamIfaceRegexs;

    private HashMap<String, TetherInterfaceSM> mIfaces;

@@ -87,6 +91,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
    private static final String DNS_DEFAULT_SERVER1 = "8.8.8.8";
    private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2";

    private boolean mDunRequired;
    private boolean mUseHiPri;
    private String mUpstreamIfaceName;

    HierarchicalStateMachine mTetherMasterSM;
@@ -114,6 +120,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_BATTERY_CHANGED);
        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        filter.addAction(Intent.ACTION_BOOT_COMPLETED);
        mStateReceiver = new StateReceiver();
        mContext.registerReceiver(mStateReceiver, filter);

@@ -129,17 +136,20 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
            tmp[1] = new String("");
            mDhcpRange = tmp;
        }
        mDunRequired = context.getResources().getBoolean(
                com.android.internal.R.bool.config_tether_dun_required);

        mTetherableUsbRegexs = context.getResources().getStringArray(
                com.android.internal.R.array.config_tether_usb_regexs);
        mTetherableWifiRegexs = context.getResources().getStringArray(
                com.android.internal.R.array.config_tether_wifi_regexs);
        mUpstreamIfaceRegexs = context.getResources().getStringArray(
                com.android.internal.R.array.config_tether_upstream_regexs);

        // TODO - remove and rely on real notifications of the current iface
        mDnsServers = new String[2];
        mDnsServers[0] = DNS_DEFAULT_SERVER1;
        mDnsServers[1] = DNS_DEFAULT_SERVER2;
        mUpstreamIfaceName = "rmnet0";
    }

    public void interfaceLinkStatusChanged(String iface, boolean link) {
@@ -426,12 +436,18 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                boolean usbConnected = (intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
                        == BatteryManager.BATTERY_PLUGGED_USB);
                if (mBooted) {
                    Tethering.this.enableUsbIfaces(usbConnected); // add or remove them
                } else {
                    mDeferedUsbConnection = usbConnected;
                }
            } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                try {
                    NetworkInfo info = service.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
                    int netType = (mUseHiPri ? ConnectivityManager.TYPE_MOBILE_HIPRI:
                                               ConnectivityManager.TYPE_MOBILE_DUN);
                    NetworkInfo info = service.getNetworkInfo(netType);
                    int msg;
                    if (info != null && info.isConnected() == true) {
                        msg = TetherMasterSM.CMD_CELL_DUN_ENABLED;
@@ -440,6 +456,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                    }
                    mTetherMasterSM.sendMessage(mTetherMasterSM.obtainMessage(msg));
                } catch (RemoteException e) {}
            } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
                mBooted = true;
                if (mDeferedUsbConnection) {
                    Tethering.this.enableUsbIfaces(true);
                }
            }
        }
    }
@@ -523,8 +544,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("up", "down");
                                // TODO - clean this up - maybe a better regex?
                                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running", "");
                                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running ","");
                                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("running","");
                                ifcg.interfaceFlags = ifcg.interfaceFlags.replace("  "," ");
                            }
                            service.setInterfaceConfig(iface, ifcg);
                        }
@@ -539,89 +559,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        return true;
    }

    private void handleTtyConnect() {
        Log.d(TAG, "handleTtyConnect");
        // for each of the available Tty not already supported by a ppp session,
        // create a ppp session
        // TODO - this should be data-driven rather than hard coded.
        String[] allowedTtys = new String[1];
        allowedTtys[0] = new String("ttyGS0");

        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

        String[] availableTtys;
        try {
            availableTtys = service.listTtys();
        } catch (RemoteException e) {
            Log.e(TAG, "error listing Ttys :" + e);
            return;
        }

        for (String tty : availableTtys) {
            for (String pattern : allowedTtys) {
                if (tty.matches(pattern)) {
                    synchronized (this) {
                        if (!mActiveTtys.contains(tty)) {
                            // TODO - don't hardcode this
                            try {
                                // local, remote, dns
                                service.attachPppd(tty, "169.254.1.128", "169.254.1.1",
                                        "169.254.1.128", "0.0.0.0");
                            } catch (Exception e) {
                                Log.e(TAG, "error calling attachPppd: " + e);
                                return;
                            }
                            Log.d(TAG, "started Pppd on tty " + tty);
                            mActiveTtys.add(tty);
                            // TODO - remove this after we detect the new iface
                            interfaceAdded("ppp0");
                        }
                    }
                }
            }
        }
    }

    private synchronized void handleTtyDisconnect() {
        Log.d(TAG, "handleTtyDisconnect");

        // TODO - this should be data-driven rather than hard coded.
        String[] allowedTtys = new String[1];
        allowedTtys[0] = new String("ttyGS0");

        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

        String[] availableTtys;
        try {
            availableTtys = service.listTtys();
        } catch (RemoteException e) {
            Log.e(TAG, "error listing Ttys :" + e);
            return;
        }

        for (String tty : availableTtys) {
            for (String pattern : allowedTtys) {
                if (tty.matches(pattern)) {
                    synchronized (this) {
                        if (mActiveTtys.contains(tty)) {
                            try {
                                service.detachPppd(tty);
                            } catch (Exception e) {
                                Log.e(TAG, "error calling detachPppd on " + tty + " :" + e);
                            }
                            mActiveTtys.remove(tty);
                            // TODO - remove this after we detect the new iface
                            interfaceRemoved("ppp0");
                            return;
                        }
                    }
                }
            }
        }
    }

    public String[] getTetherableUsbRegexs() {
        return mTetherableUsbRegexs;
    }
@@ -630,6 +567,14 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        return mTetherableWifiRegexs;
    }

    public String[] getUpstreamIfaceRegexs() {
        return mUpstreamIfaceRegexs;
    }

    public boolean isDunRequired() {
        return mDunRequired;
    }

    public String[] getTetheredIfaces() {
        ArrayList<String> list = new ArrayList<String>();
        synchronized (mIfaces) {
@@ -1217,7 +1162,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                int retValue = Phone.APN_REQUEST_FAILED;
                try {
                    retValue = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                            Phone.FEATURE_ENABLE_DUN, new Binder());
                            (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN),
                            new Binder());
                } catch (Exception e) {
                }
                return retValue;
@@ -1228,7 +1174,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        IConnectivityManager.Stub.asInterface(b);
                try {
                    service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
                            Phone.FEATURE_ENABLE_DUN);
                            (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN));
                } catch (Exception e) {
                    return false;
                }
@@ -1278,9 +1224,45 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                transitionTo(mInitialState);
                return true;
            }
            public String findActiveUpstreamIface() {
                // check for what iface we can use - if none found switch to error.
                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
                INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);

                String[] ifaces = new String[0];
                try {
                    ifaces = service.listInterfaces();
                } catch (Exception e) {
                    Log.e(TAG, "Error listing Interfaces :" + e);
                    return null;
                }
                for (String iface : ifaces) {
                    for (String regex : mUpstreamIfaceRegexs) {
                        if (iface.matches(regex)) {
                            // verify it is up!
                            InterfaceConfiguration ifcg = null;
                            try {
                                ifcg = service.getInterfaceConfig(iface);
                            } catch (Exception e) {
                                Log.e(TAG, "Error getting iface config :" + e);
                                // ignore - try next
                                continue;
                            }
                            if (ifcg.interfaceFlags.contains("up")) {
                                return iface;
                            }
                        }
                    }
                }
                return null;
            }
        }

        class InitialState extends TetherMasterUtilState {
            @Override
            public void enter() {
                mUseHiPri = false;
            }
            @Override
            public boolean processMessage(Message message) {
                Log.d(TAG, "MasterInitialState.processMessage what=" + message.what);
@@ -1313,6 +1295,8 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        class CellDunRequestedState extends TetherMasterUtilState {
            @Override
            public void enter() {
                mUseHiPri = (findActiveUpstreamIface() == null && !mDunRequired);
                if (mDunRequired || mUseHiPri) {
                    ++mSequenceNumber;
                    int result = turnOnMobileDun();
                    switch (result) {
@@ -1334,7 +1318,12 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                            sendMessageDelayed(m, CELL_DUN_TIMEOUT_MS);
                            break;
                        default:
                        Log.e(TAG, "Unknown return value from startUsingNetworkFeature " + result);
                            Log.e(TAG, "Unknown return value from startUsingNetworkFeature " +
                                    result);
                    }
                } else {
                    Log.d(TAG, "no Dun Required.  Skipping to Active");
                    sendMessage(obtainMessage(CMD_CELL_DUN_ENABLED));
                }
            }

@@ -1353,7 +1342,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        if (index != -1) {
                            mNotifyList.remove(index);
                            if (mNotifyList.isEmpty()) {
                                if (mDunRequired || mUseHiPri) {
                                    turnOffMobileDun();
                                }
                                transitionTo(mInitialState);
                            }
                        }
@@ -1399,7 +1390,9 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        if (index != -1) {
                            mNotifyList.remove(index);
                            if (mNotifyList.isEmpty()) {
                                if (mDunRequired || mUseHiPri) {
                                    turnOffMobileDun();
                                }
                                transitionTo(mInitialState);
                            }
                        }
@@ -1424,13 +1417,21 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
        class TetherModeAliveState extends TetherMasterUtilState {
            @Override
            public void enter() {
                if (mDunRequired || mUseHiPri) {
                    Log.d(TAG, "renewing Dun in " + CELL_DUN_RENEW_MS + "ms");
                    sendMessageDelayed(obtainMessage(CMD_CELL_DUN_RENEW), CELL_DUN_RENEW_MS);
                }
                mUpstreamIfaceName = findActiveUpstreamIface();
                if (mUpstreamIfaceName == null) {
                    Log.d(TAG, "Erroring our of tether - no upstream ifaces available");
                    sendMessage(obtainMessage(CMD_CELL_DUN_DISABLED));
                } else {
                    for (Object o : mNotifyList) {
                        TetherInterfaceSM sm = (TetherInterfaceSM)o;
                        sm.sendMessage(sm.obtainMessage(TetherInterfaceSM.CMD_TETHER_MODE_ALIVE));
                    }
                }
            }
            @Override
            public boolean processMessage(Message message) {
                Log.d(TAG, "TetherModeAliveState.processMessage what=" + message.what);
@@ -1447,8 +1448,11 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                        if (index != -1) {
                            mNotifyList.remove(index);
                            if (mNotifyList.isEmpty()) {
                                if (mDunRequired || mUseHiPri) {
                                    turnOffMobileDun();
                                }
                                turnOffMasterTetherSettings(); // transitions appropriately
                                mUpstreamIfaceName = null;
                            }
                        }
                        break;
@@ -1461,6 +1465,7 @@ public class Tethering extends INetworkManagementEventObserver.Stub {
                                    TetherInterfaceSM.CMD_TETHER_MODE_DEAD));
                        }
                        turnOffMasterTetherSettings(); // transitions appropriately
                        mUpstreamIfaceName = null;
                        break;
                    case CMD_CELL_DUN_RENEW:
                        Log.d(TAG, "renewing dun connection - requeuing for another " +