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
This commit is contained in:
Yuuki Habu
2020-02-05 16:24:52 +09:00
committed by Lorenzo Colitti
parent 856079384a
commit 557e457278
3 changed files with 95 additions and 0 deletions

View File

@@ -3812,6 +3812,12 @@
<!-- Bluetooth Tethering settings. Message for untethering from a bluetooth device [CHAR LIMIT=50]--> <!-- Bluetooth Tethering settings. Message for untethering from a bluetooth device [CHAR LIMIT=50]-->
<string name="bluetooth_untether_blank"><xliff:g id="device_name">%1$s</xliff:g> will be untethered.</string> <string name="bluetooth_untether_blank"><xliff:g id="device_name">%1$s</xliff:g> will be untethered.</string>
<!-- Ethernet Tethering settings-->
<!-- Label for ethernet tether checkbox [CHAR LIMIT=25]-->
<string name="ethernet_tether_checkbox_text">Ethernet tethering</string>
<!-- Ethernet Tethering subtext [CHAR LIMIT=70]-->
<string name="ethernet_tethering_subtext" product="default">Share phone\u2019s internet connection via USB Ethernet</string>
<!-- Tethering footer info [CHAR LIMIT=NONE]--> <!-- Tethering footer info [CHAR LIMIT=NONE]-->
<string name="tethering_footer_info">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.</string> <string name="tethering_footer_info">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.</string>
<!-- Tethering footer info for the device which supports Wi-Fi and Wi-Fi tethering enabled at the same time [CHAR LIMIT=NONE]--> <!-- Tethering footer info for the device which supports Wi-Fi and Wi-Fi tethering enabled at the same time [CHAR LIMIT=NONE]-->

View File

@@ -38,6 +38,12 @@
android:summary="@string/bluetooth_tethering_subtext" android:summary="@string/bluetooth_tethering_subtext"
settings:keywords="@string/keywords_hotspot_tethering" /> settings:keywords="@string/keywords_hotspot_tethering" />
<SwitchPreference
android:key="enable_ethernet_tethering"
android:title="@string/ethernet_tether_checkbox_text"
android:summary="@string/ethernet_tethering_subtext"
settings:keywords="@string/keywords_hotspot_tethering" />
<Preference <Preference
android:key="disabled_on_data_saver" android:key="disabled_on_data_saver"
android:summary="@string/tether_settings_disabled_on_data_saver" android:summary="@string/tether_settings_disabled_on_data_saver"

View File

@@ -18,6 +18,7 @@ package com.android.settings;
import static android.net.ConnectivityManager.TETHERING_BLUETOOTH; import static android.net.ConnectivityManager.TETHERING_BLUETOOTH;
import static android.net.ConnectivityManager.TETHERING_USB; import static android.net.ConnectivityManager.TETHERING_USB;
import static android.net.TetheringManager.TETHERING_ETHERNET;
import android.app.Activity; import android.app.Activity;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
@@ -31,12 +32,16 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.EthernetManager;
import android.net.TetheringManager;
import android.net.wifi.WifiManager; import android.net.wifi.WifiManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.UserManager; import android.os.UserManager;
import android.provider.SearchIndexableResource; import android.provider.SearchIndexableResource;
import android.text.TextUtils;
import android.util.FeatureFlagUtils; import android.util.FeatureFlagUtils;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
@@ -71,6 +76,7 @@ public class TetherSettings extends RestrictedSettingsFragment
static final String KEY_USB_TETHER_SETTINGS = "usb_tether_settings"; static final String KEY_USB_TETHER_SETTINGS = "usb_tether_settings";
@VisibleForTesting @VisibleForTesting
static final String KEY_ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering"; static final String KEY_ENABLE_BLUETOOTH_TETHERING = "enable_bluetooth_tethering";
private static final String KEY_ENABLE_ETHERNET_TETHERING = "enable_ethernet_tethering";
private static final String KEY_DATA_SAVER_FOOTER = "disabled_on_data_saver"; private static final String KEY_DATA_SAVER_FOOTER = "disabled_on_data_saver";
@VisibleForTesting @VisibleForTesting
static final String KEY_TETHER_PREFS_FOOTER = "tether_prefs_footer"; static final String KEY_TETHER_PREFS_FOOTER = "tether_prefs_footer";
@@ -81,15 +87,22 @@ public class TetherSettings extends RestrictedSettingsFragment
private SwitchPreference mBluetoothTether; private SwitchPreference mBluetoothTether;
private SwitchPreference mEthernetTether;
private BroadcastReceiver mTetherChangeReceiver; private BroadcastReceiver mTetherChangeReceiver;
private String[] mUsbRegexs; private String[] mUsbRegexs;
private String[] mBluetoothRegexs; private String[] mBluetoothRegexs;
private String mEthernetRegex;
private AtomicReference<BluetoothPan> mBluetoothPan = new AtomicReference<>(); private AtomicReference<BluetoothPan> mBluetoothPan = new AtomicReference<>();
private Handler mHandler = new Handler(); private Handler mHandler = new Handler();
private OnStartTetheringCallback mStartTetheringCallback; private OnStartTetheringCallback mStartTetheringCallback;
private ConnectivityManager mCm; private ConnectivityManager mCm;
private EthernetManager mEm;
private TetheringManager mTm;
private TetheringEventCallback mTetheringEventCallback;
private EthernetListener mEthernetListener;
private WifiTetherPreferenceController mWifiTetherPreferenceController; private WifiTetherPreferenceController mWifiTetherPreferenceController;
@@ -144,17 +157,23 @@ public class TetherSettings extends RestrictedSettingsFragment
mUsbTether = (SwitchPreference) findPreference(KEY_USB_TETHER_SETTINGS); mUsbTether = (SwitchPreference) findPreference(KEY_USB_TETHER_SETTINGS);
mBluetoothTether = (SwitchPreference) findPreference(KEY_ENABLE_BLUETOOTH_TETHERING); mBluetoothTether = (SwitchPreference) findPreference(KEY_ENABLE_BLUETOOTH_TETHERING);
mEthernetTether = (SwitchPreference) findPreference(KEY_ENABLE_ETHERNET_TETHERING);
setFooterPreferenceTitle(); setFooterPreferenceTitle();
mDataSaverBackend.addListener(this); mDataSaverBackend.addListener(this);
mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); mCm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
mEm = (EthernetManager) getSystemService(Context.ETHERNET_SERVICE);
mTm = (TetheringManager) getSystemService(Context.TETHERING_SERVICE);
mUsbRegexs = mCm.getTetherableUsbRegexs(); mUsbRegexs = mCm.getTetherableUsbRegexs();
mBluetoothRegexs = mCm.getTetherableBluetoothRegexs(); mBluetoothRegexs = mCm.getTetherableBluetoothRegexs();
mEthernetRegex = getContext().getResources().getString(
com.android.internal.R.string.config_ethernet_iface_regex);
final boolean usbAvailable = mUsbRegexs.length != 0; final boolean usbAvailable = mUsbRegexs.length != 0;
final boolean bluetoothAvailable = mBluetoothRegexs.length != 0; final boolean bluetoothAvailable = mBluetoothRegexs.length != 0;
final boolean ethernetAvailable = !TextUtils.isEmpty(mEthernetRegex);
if (!usbAvailable || Utils.isMonkeyRunning()) { if (!usbAvailable || Utils.isMonkeyRunning()) {
getPreferenceScreen().removePreference(mUsbTether); getPreferenceScreen().removePreference(mUsbTether);
@@ -172,6 +191,7 @@ public class TetherSettings extends RestrictedSettingsFragment
mBluetoothTether.setChecked(false); mBluetoothTether.setChecked(false);
} }
} }
if (!ethernetAvailable) getPreferenceScreen().removePreference(mEthernetTether);
// Set initial state based on Data Saver mode. // Set initial state based on Data Saver mode.
onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled()); onDataSaverChanged(mDataSaverBackend.isDataSaverEnabled());
} }
@@ -194,6 +214,7 @@ public class TetherSettings extends RestrictedSettingsFragment
mDataSaverEnabled = isDataSaving; mDataSaverEnabled = isDataSaving;
mUsbTether.setEnabled(!mDataSaverEnabled); mUsbTether.setEnabled(!mDataSaverEnabled);
mBluetoothTether.setEnabled(!mDataSaverEnabled); mBluetoothTether.setEnabled(!mDataSaverEnabled);
mEthernetTether.setEnabled(!mDataSaverEnabled);
mDataSaverFooter.setVisible(mDataSaverEnabled); mDataSaverFooter.setVisible(mDataSaverEnabled);
} }
@@ -221,6 +242,7 @@ public class TetherSettings extends RestrictedSettingsFragment
@Override @Override
public void onReceive(Context content, Intent intent) { public void onReceive(Context content, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
// TODO: stop using ACTION_TETHER_STATE_CHANGED and use mTetheringEventCallback instead.
if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) { if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
// TODO - this should understand the interface types // TODO - this should understand the interface types
ArrayList<String> available = intent.getStringArrayListExtra( ArrayList<String> available = intent.getStringArrayListExtra(
@@ -279,6 +301,8 @@ public class TetherSettings extends RestrictedSettingsFragment
final Activity activity = getActivity(); final Activity activity = getActivity();
mStartTetheringCallback = new OnStartTetheringCallback(this); mStartTetheringCallback = new OnStartTetheringCallback(this);
mTetheringEventCallback = new TetheringEventCallback();
mTm.registerTetheringEventCallback(new HandlerExecutor(mHandler), mTetheringEventCallback);
mMassStorageActive = Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState()); mMassStorageActive = Environment.MEDIA_SHARED.equals(Environment.getExternalStorageState());
mTetherChangeReceiver = new TetherChangeReceiver(); mTetherChangeReceiver = new TetherChangeReceiver();
@@ -301,6 +325,9 @@ public class TetherSettings extends RestrictedSettingsFragment
if (intent != null) mTetherChangeReceiver.onReceive(activity, intent); if (intent != null) mTetherChangeReceiver.onReceive(activity, intent);
mEthernetListener = new EthernetListener();
mEm.addListener(mEthernetListener);
updateState(); updateState();
} }
@@ -312,8 +339,12 @@ public class TetherSettings extends RestrictedSettingsFragment
return; return;
} }
getActivity().unregisterReceiver(mTetherChangeReceiver); getActivity().unregisterReceiver(mTetherChangeReceiver);
mTm.unregisterTetheringEventCallback(mTetheringEventCallback);
mEm.removeListener(mEthernetListener);
mTetherChangeReceiver = null; mTetherChangeReceiver = null;
mStartTetheringCallback = null; mStartTetheringCallback = null;
mTetheringEventCallback = null;
mEthernetListener = null;
} }
private void updateState() { private void updateState() {
@@ -327,6 +358,7 @@ public class TetherSettings extends RestrictedSettingsFragment
String[] errored) { String[] errored) {
updateUsbState(available, tethered, errored); updateUsbState(available, tethered, errored);
updateBluetoothState(); updateBluetoothState();
updateEthernetState(available, tethered);
} }
private void updateUsbState(String[] available, String[] 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) { public static boolean isProvisioningNeededButUnavailable(Context context) {
return (TetherUtil.isProvisioningNeeded(context) return (TetherUtil.isProvisioningNeeded(context)
&& !isIntentAvailable(context)); && !isIntentAvailable(context));
@@ -438,6 +495,12 @@ public class TetherSettings extends RestrictedSettingsFragment
} else { } else {
mCm.stopTethering(TETHERING_BLUETOOTH); mCm.stopTethering(TETHERING_BLUETOOTH);
} }
} else if (preference == mEthernetTether) {
if (mEthernetTether.isChecked()) {
startTethering(TETHERING_ETHERNET);
} else {
mCm.stopTethering(TETHERING_ETHERNET);
}
} }
return super.onPreferenceTreeClick(preference); return super.onPreferenceTreeClick(preference);
@@ -495,6 +558,13 @@ public class TetherSettings extends RestrictedSettingsFragment
if (!bluetoothAvailable) { if (!bluetoothAvailable) {
keys.add(KEY_ENABLE_BLUETOOTH_TETHERING); 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; return keys;
} }
}; };
@@ -524,4 +594,17 @@ public class TetherSettings extends RestrictedSettingsFragment
} }
} }
} }
private final class TetheringEventCallback implements TetheringManager.TetheringEventCallback {
@Override
public void onTetheredInterfacesChanged(List<String> interfaces) {
updateState();
}
}
private final class EthernetListener implements EthernetManager.Listener {
public void onAvailabilityChanged(String iface, boolean isAvailable) {
mHandler.post(TetherSettings.this::updateState);
}
}
} }