From 557e457278a1524d8d4d2b7619e23c6ff03322e7 Mon Sep 17 00:00:00 2001 From: Yuuki Habu Date: Wed, 5 Feb 2020 16:24:52 +0900 Subject: [PATCH] Add Ethernet Tethering settings Add Ethernet Tethering settings - Show prefernce if config_ethernet_iface_regex is set - Activate if tethered ethernet interface is exist Bug: 148824036 Test: manual test - update prefernce plug-in, plug-out Change-Id: Ia4f365ddc1a53a926d716046db3e6ac463c978b9 --- res/values/strings.xml | 6 ++ res/xml/tether_prefs.xml | 6 ++ src/com/android/settings/TetherSettings.java | 83 ++++++++++++++++++++ 3 files changed, 95 insertions(+) diff --git a/res/values/strings.xml b/res/values/strings.xml index a695b1ace40..d01f8be555a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -3812,6 +3812,12 @@ %1$s will be untethered. + + + Ethernet tethering + + Share phone\u2019s internet connection via USB Ethernet + Use hotspot and tethering to provide internet to other devices through your mobile data connection. Apps can also create a hotspot to share content with nearby devices. diff --git a/res/xml/tether_prefs.xml b/res/xml/tether_prefs.xml index abc49cc9ff9..9367a9bbf62 100644 --- a/res/xml/tether_prefs.xml +++ b/res/xml/tether_prefs.xml @@ -38,6 +38,12 @@ android:summary="@string/bluetooth_tethering_subtext" settings:keywords="@string/keywords_hotspot_tethering" /> + + mBluetoothPan = new AtomicReference<>(); private Handler mHandler = new Handler(); private OnStartTetheringCallback mStartTetheringCallback; private ConnectivityManager mCm; + private EthernetManager mEm; + private TetheringManager mTm; + private TetheringEventCallback mTetheringEventCallback; + private EthernetListener mEthernetListener; private WifiTetherPreferenceController mWifiTetherPreferenceController; @@ -144,17 +157,23 @@ public class TetherSettings extends RestrictedSettingsFragment mUsbTether = (SwitchPreference) findPreference(KEY_USB_TETHER_SETTINGS); mBluetoothTether = (SwitchPreference) findPreference(KEY_ENABLE_BLUETOOTH_TETHERING); + mEthernetTether = (SwitchPreference) findPreference(KEY_ENABLE_ETHERNET_TETHERING); setFooterPreferenceTitle(); mDataSaverBackend.addListener(this); mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + mEm = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE); + mTm = (TetheringManager) getSystemService(Context.TETHERING_SERVICE); mUsbRegexs = mCm.getTetherableUsbRegexs(); mBluetoothRegexs = mCm.getTetherableBluetoothRegexs(); + mEthernetRegex = getContext().getResources().getString( + com.android.internal.R.string.config_ethernet_iface_regex); final boolean usbAvailable = mUsbRegexs.length != 0; final boolean bluetoothAvailable = mBluetoothRegexs.length != 0; + final boolean ethernetAvailable = !TextUtils.isEmpty(mEthernetRegex); if (!usbAvailable || Utils.isMonkeyRunning()) { getPreferenceScreen().removePreference(mUsbTether); @@ -172,6 +191,7 @@ public class TetherSettings extends RestrictedSettingsFragment mBluetoothTether.setChecked(false); } } + if (!ethernetAvailable) getPreferenceScreen().removePreference(mEthernetTether); // Set initial state based on Data Saver mode. onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled()); } @@ -194,6 +214,7 @@ public class TetherSettings extends RestrictedSettingsFragment mDataSaverEnabled = isDataSaving; mUsbTether.setEnabled(!mDataSaverEnabled); mBluetoothTether.setEnabled(!mDataSaverEnabled); + mEthernetTether.setEnabled(!mDataSaverEnabled); mDataSaverFooter.setVisible(mDataSaverEnabled); } @@ -221,6 +242,7 @@ public class TetherSettings extends RestrictedSettingsFragment @Override public void onReceive(Context content, Intent intent) { String action = intent.getAction(); + // TODO: stop using ACTION_TETHER_STATE_CHANGED and use mTetheringEventCallback instead. if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) { // TODO - this should understand the interface types ArrayList available = intent.getStringArrayListExtra( @@ -279,6 +301,8 @@ public class TetherSettings extends RestrictedSettingsFragment final Activity activity = getActivity(); mStartTetheringCallback = new OnStartTetheringCallback(this); + mTetheringEventCallback = new TetheringEventCallback(); + mTm.registerTetheringEventCallback(new HandlerExecutor(mHandler), mTetheringEventCallback); mMassStorageActive = Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState()); mTetherChangeReceiver = new TetherChangeReceiver(); @@ -301,6 +325,9 @@ public class TetherSettings extends RestrictedSettingsFragment if (intent != null) mTetherChangeReceiver.onReceive(activity, intent); + mEthernetListener = new EthernetListener(); + mEm.addListener(mEthernetListener); + updateState(); } @@ -312,8 +339,12 @@ public class TetherSettings extends RestrictedSettingsFragment return; } getActivity().unregisterReceiver(mTetherChangeReceiver); + mTm.unregisterTetheringEventCallback(mTetheringEventCallback); + mEm.removeListener(mEthernetListener); mTetherChangeReceiver = null; mStartTetheringCallback = null; + mTetheringEventCallback = null; + mEthernetListener = null; } private void updateState() { @@ -327,6 +358,7 @@ public class TetherSettings extends RestrictedSettingsFragment String[] errored) { updateUsbState(available, tethered, errored); updateBluetoothState(); + updateEthernetState(available, tethered); } private void updateUsbState(String[] available, String[] tethered, @@ -390,6 +422,31 @@ public class TetherSettings extends RestrictedSettingsFragment } } + private void updateEthernetState(String[] available, String[] tethered) { + + boolean isAvailable = false; + boolean isTethered = false; + + for (String s : available) { + if (s.matches(mEthernetRegex)) isAvailable = true; + } + + for (String s : tethered) { + if (s.matches(mEthernetRegex)) isTethered = true; + } + + if (isTethered) { + mEthernetTether.setEnabled(!mDataSaverEnabled); + mEthernetTether.setChecked(true); + } else if (isAvailable || mEm.isAvailable()) { + mEthernetTether.setEnabled(!mDataSaverEnabled); + mEthernetTether.setChecked(false); + } else { + mEthernetTether.setEnabled(false); + mEthernetTether.setChecked(false); + } + } + public static boolean isProvisioningNeededButUnavailable(Context context) { return (TetherUtil.isProvisioningNeeded(context) && !isIntentAvailable(context)); @@ -438,6 +495,12 @@ public class TetherSettings extends RestrictedSettingsFragment } else { mCm.stopTethering(TETHERING_BLUETOOTH); } + } else if (preference == mEthernetTether) { + if (mEthernetTether.isChecked()) { + startTethering(TETHERING_ETHERNET); + } else { + mCm.stopTethering(TETHERING_ETHERNET); + } } return super.onPreferenceTreeClick(preference); @@ -495,6 +558,13 @@ public class TetherSettings extends RestrictedSettingsFragment if (!bluetoothAvailable) { keys.add(KEY_ENABLE_BLUETOOTH_TETHERING); } + + final boolean ethernetAvailable = !TextUtils.isEmpty( + context.getResources().getString( + com.android.internal.R.string.config_ethernet_iface_regex)); + if (!ethernetAvailable) { + keys.add(KEY_ENABLE_ETHERNET_TETHERING); + } return keys; } }; @@ -524,4 +594,17 @@ public class TetherSettings extends RestrictedSettingsFragment } } } + + private final class TetheringEventCallback implements TetheringManager.TetheringEventCallback { + @Override + public void onTetheredInterfacesChanged(List interfaces) { + updateState(); + } + } + + private final class EthernetListener implements EthernetManager.Listener { + public void onAvailabilityChanged(String iface, boolean isAvailable) { + mHandler.post(TetherSettings.this::updateState); + } + } }