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

Commit 419ab66b authored by Robert Greenwalt's avatar Robert Greenwalt Committed by Android (Google) Code Review
Browse files

Merge "Add build options for tethering."

parents 7895da44 c9d5fb7c
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 " +