Loading src/com/android/settings/AllInOneTetherSettings.java +45 −31 Original line number Diff line number Diff line Loading @@ -20,21 +20,20 @@ import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION; import static com.android.settings.network.WifiTetherDisablePreferenceController .KEY_ENABLE_WIFI_TETHERING; import static com.android.settings.network.WifiTetherDisablePreferenceController.KEY_ENABLE_WIFI_TETHERING; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.UserManager; import android.text.TextUtils; import android.util.Log; Loading @@ -47,6 +46,8 @@ import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.datausage.DataSaverBackend; import com.android.settings.network.TetherEnabler; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SwitchBarController; import com.android.settings.wifi.tether.WifiTetherApBandPreferenceController; import com.android.settings.wifi.tether.WifiTetherAutoOffPreferenceController; import com.android.settings.wifi.tether.WifiTetherBasePreferenceController; Loading @@ -59,10 +60,10 @@ import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** * Displays preferences for Tethering. * TODO(b/147322704): Use TetherEnabler in this fragment to manage tethering switch on/off. * Displays preferences for all Tethering options. * TODO(b/147323306): Add tether option preferences into this fragment after controllers created. */ @SearchIndexable Loading Loading @@ -96,6 +97,7 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment private WifiManager mWifiManager; private boolean mRestartWifiApAfterConfigChange; private final AtomicReference<BluetoothPan> mBluetoothPan = new AtomicReference<>(); private WifiTetherSSIDPreferenceController mSSIDPreferenceController; private WifiTetherPasswordPreferenceController mPasswordPreferenceController; Loading @@ -103,8 +105,8 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment private WifiTetherSecurityPreferenceController mSecurityPreferenceController; private PreferenceGroup mWifiTetherGroup; private SharedPreferences mSharedPreferences; private ConnectivityManager mConnectivityManager; private boolean mWifiTetherChosen; private TetherEnabler mTetherEnabler; private final BroadcastReceiver mTetherChangeReceiver = new BroadcastReceiver() { @Override Loading @@ -118,19 +120,30 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_DISABLED && mRestartWifiApAfterConfigChange) { mRestartWifiApAfterConfigChange = false; startTether(); mTetherEnabler.startTethering(TETHERING_WIFI); } } else if (TextUtils.equals(action, WIFI_AP_STATE_CHANGED_ACTION)) { int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0); if (state == WifiManager.WIFI_AP_STATE_DISABLED && mRestartWifiApAfterConfigChange) { mRestartWifiApAfterConfigChange = false; startTether(); mTetherEnabler.startTethering(TETHERING_WIFI); } } } }; private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { mBluetoothPan.set((BluetoothPan) proxy); } public void onServiceDisconnected(int profile) { mBluetoothPan.set(null); } }; @Override public int getMetricsCategory() { return SettingsEnums.TETHER; Loading @@ -144,8 +157,6 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment public void onAttach(Context context) { super.onAttach(context); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mSharedPreferences = context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE); Loading Loading @@ -181,6 +192,27 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment // TODO(b/147325229): Hide advanced settings like security and ap band. } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (mUnavailable) { return; } // Assume we are in a SettingsActivity. This is only safe because we currently use // SettingsActivity as base for all preference fragments. final SettingsActivity activity = (SettingsActivity) getActivity(); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { adapter.getProfileProxy(activity.getApplicationContext(), mProfileServiceListener, BluetoothProfile.PAN); } final SwitchBar switchBar = activity.getSwitchBar(); mTetherEnabler = new TetherEnabler(activity, new SwitchBarController(switchBar), mBluetoothPan); getSettingsLifecycle().addObserver(mTetherEnabler); switchBar.show(); } @Override public void onStart() { super.onStart(); Loading Loading @@ -297,8 +329,7 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment Log.d(TAG, "Wifi AP config changed while enabled, stop and restart"); } mRestartWifiApAfterConfigChange = true; // TODO(b/147322704): Use TethetEnabler to stop tethering. mConnectivityManager.stopTethering(TETHERING_WIFI); mTetherEnabler.stopTethering(TETHERING_WIFI); } if (controller instanceof WifiTetherSecurityPreferenceController) { Loading Loading @@ -335,23 +366,6 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment } } private void startTether() { // TODO(b/147322704): Use TetherEnabler to start tethering. if (mWifiManager.isWifiApEnabled()) { return; } mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, true /*showProvisioningUi*/, new ConnectivityManager.OnStartTetheringCallback() { @Override public void onTetheringFailed() { super.onTetheringFailed(); // Do nothing. There is no UI to update at this point. } }, new Handler(Looper.getMainLooper())); } private void reConfigInitialExpandedChildCount() { getPreferenceScreen().setInitialExpandedChildrenCount(getInitialExpandedChildCount()); } Loading src/com/android/settings/network/BluetoothTetherPreferenceController.java +1 −2 Original line number Diff line number Diff line Loading @@ -47,8 +47,7 @@ public final class BluetoothTetherPreferenceController extends AbstractPreferenc private static final String TAG = "BluetoothTetherPreferenceController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String PREF_KEY = "enable_bluetooth_tethering"; public static final String PREF_KEY = "enable_bluetooth_tethering"; private final ConnectivityManager mCm; private int mBluetoothState; private Preference mPreference; Loading src/com/android/settings/network/TetherEnabler.java +125 −42 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settings.datausage.DataSaverBackend; import com.android.settings.widget.SwitchWidgetController; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicReference; Loading Loading @@ -78,14 +79,7 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang private final Context mContext; @VisibleForTesting final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback = new ConnectivityManager.OnStartTetheringCallback() { @Override public void onTetheringFailed() { super.onTetheringFailed(); mSwitchWidgetController.setChecked(false); } }; ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback; private final AtomicReference<BluetoothPan> mBluetoothPan; private final SharedPreferences mSharedPreferences; private boolean mBluetoothEnableForTether; Loading @@ -110,11 +104,15 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang mDataSaverBackend.addListener(this); mSwitchWidgetController.setListener(this); mSwitchWidgetController.startListening(); IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); final IntentFilter filter = new IntentFilter( ConnectivityManager.ACTION_TETHER_STATE_CHANGED); filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); mContext.registerReceiver(mTetherChangeReceiver, filter); mSwitchWidgetController.setChecked(isTethering()); setSwitchWidgetEnabled(true); mOnStartTetheringCallback = new OnStartTetheringCallback(this); updateState(); } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) Loading @@ -134,8 +132,14 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang mContext.unregisterReceiver(mTetherChangeReceiver); } private void setSwitchWidgetEnabled(boolean enabled) { mSwitchWidgetController.setEnabled(enabled && !mDataSaverEnabled); private void updateState() { mSwitchWidgetController.setChecked(isTethering()); mSwitchWidgetController.setEnabled(!mDataSaverEnabled); } private void updateState(String[] tethered) { mSwitchWidgetController.setChecked(isTethering(tethered)); mSwitchWidgetController.setEnabled(!mDataSaverEnabled); } private boolean isTethering() { Loading @@ -148,6 +152,10 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang return true; } if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) { return true; } final BluetoothPan pan = mBluetoothPan.get(); return pan != null && pan.isTetheringOn(); Loading @@ -155,29 +163,39 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang @Override public boolean onSwitchToggled(boolean isChecked) { if (isChecked) { if (isChecked && !isTethering()) { startTether(); } else { } if (!isChecked && isTethering()) { stopTether(); } return true; } @VisibleForTesting void stopTether() { private void stopTether() { // Wi-Fi tether is selected by default. if (mSharedPreferences.getBoolean(WIFI_TETHER_KEY, true)) { mConnectivityManager.stopTethering(TETHERING_WIFI); stopTethering(TETHERING_WIFI); } if (mSharedPreferences.getBoolean(USB_TETHER_KEY, false)) { mConnectivityManager.stopTethering(TETHERING_USB); stopTethering(TETHERING_USB); } if (mSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)) { mConnectivityManager.stopTethering(TETHERING_BLUETOOTH); stopTethering(TETHERING_BLUETOOTH); } } /** * Use this method to stop a single choice of tethering. * * @param choice The choice of tethering to stop. */ public void stopTethering(int choice) { mConnectivityManager.stopTethering(choice); } @VisibleForTesting Loading @@ -197,8 +215,16 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang } } @VisibleForTesting void startTethering(int choice) { /** * Use this method to start a single choice of tethering. * For bluetooth tethering, it will first turn on bluetooth if bluetooth is off. * For Wi-Fi tethering, it will be no-op if Wi-Fi tethering already active. * * @param choice The choice of tethering to start. */ public void startTethering(int choice) { mSwitchWidgetController.setEnabled(false); if (choice == TETHERING_WIFI && mWifiManager.isWifiApEnabled()) { if (DEBUG) { Log.d(TAG, "Wifi tether already active!"); Loading @@ -224,15 +250,32 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang private final BroadcastReceiver mTetherChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); final String action = intent.getAction(); ArrayList<String> active = null; boolean shouldUpdateState = false; if (TextUtils.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED, action)) { ArrayList<String> active = intent.getStringArrayListExtra( ConnectivityManager.EXTRA_ACTIVE_TETHER); mSwitchWidgetController.setChecked( isTethering(active.toArray(new String[active.size()]))); active = intent.getStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER); shouldUpdateState = true; } else if (TextUtils.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION, action)) { shouldUpdateState = handleWifiApStateChanged(intent.getIntExtra( WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED)); } else if (TextUtils.equals(BluetoothAdapter.ACTION_STATE_CHANGED, action)) { switch (intent .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { shouldUpdateState = handleBluetoothStateChanged(intent .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)); } if (shouldUpdateState) { if (active != null) { updateState(active.toArray(new String[0])); } else { updateState(); } } } }; private boolean handleBluetoothStateChanged(int state) { switch (state) { case BluetoothAdapter.STATE_ON: if (mBluetoothEnableForTether) { startTethering(TETHERING_BLUETOOTH); Loading @@ -242,18 +285,32 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang // Fall through. case BluetoothAdapter.ERROR: mBluetoothEnableForTether = false; break; return true; default: // ignore transition states // Return false for transition states. return false; } } private boolean handleWifiApStateChanged(int state) { switch (state) { case WifiManager.WIFI_AP_STATE_FAILED: Log.e(TAG, "Wifi AP is failed!"); // fall through case WifiManager.WIFI_AP_STATE_ENABLED: // fall through case WifiManager.WIFI_AP_STATE_DISABLED: return true; default: // return false for transition state return false; } } }; @Override public void onDataSaverChanged(boolean isDataSaving) { mDataSaverEnabled = isDataSaving; setSwitchWidgetEnabled(!isDataSaving); mSwitchWidgetController.setEnabled(!isDataSaving); } @Override Loading Loading @@ -291,4 +348,30 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang } } } private static final class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { final WeakReference<TetherEnabler> mTetherEnabler; OnStartTetheringCallback(TetherEnabler enabler) { mTetherEnabler = new WeakReference<>(enabler); } @Override public void onTetheringStarted() { update(); } @Override public void onTetheringFailed() { update(); } private void update() { TetherEnabler enabler = mTetherEnabler.get(); if (enabler != null) { enabler.updateState(); } } } } src/com/android/settings/network/UsbTetherPreferenceController.java +1 −2 Original line number Diff line number Diff line Loading @@ -49,8 +49,7 @@ public final class UsbTetherPreferenceController extends AbstractPreferenceContr private static final String TAG = "UsbTetherPrefController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String PREF_KEY = "enable_usb_tethering"; public static final String PREF_KEY = "enable_usb_tethering"; private final ConnectivityManager mCm; private boolean mUsbConnected; Loading tests/robotests/src/com/android/settings/network/TetherEnablerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -109,8 +109,10 @@ public class TetherEnablerTest { @Test public void startTether_fail_resetSwitchBar() { when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(false); mEnabler.onStart(); mEnabler.startTether(); when(mConnectivityManager.getTetheredIfaces()).thenReturn(new String[0]); mEnabler.mOnStartTetheringCallback.onTetheringFailed(); assertThat(mSwitchBar.isChecked()).isFalse(); Loading Loading
src/com/android/settings/AllInOneTetherSettings.java +45 −31 Original line number Diff line number Diff line Loading @@ -20,21 +20,20 @@ import static android.net.ConnectivityManager.ACTION_TETHER_STATE_CHANGED; import static android.net.ConnectivityManager.TETHERING_WIFI; import static android.net.wifi.WifiManager.WIFI_AP_STATE_CHANGED_ACTION; import static com.android.settings.network.WifiTetherDisablePreferenceController .KEY_ENABLE_WIFI_TETHERING; import static com.android.settings.network.WifiTetherDisablePreferenceController.KEY_ENABLE_WIFI_TETHERING; import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothPan; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.net.ConnectivityManager; import android.net.wifi.SoftApConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.UserManager; import android.text.TextUtils; import android.util.Log; Loading @@ -47,6 +46,8 @@ import com.android.settings.dashboard.RestrictedDashboardFragment; import com.android.settings.datausage.DataSaverBackend; import com.android.settings.network.TetherEnabler; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SwitchBarController; import com.android.settings.wifi.tether.WifiTetherApBandPreferenceController; import com.android.settings.wifi.tether.WifiTetherAutoOffPreferenceController; import com.android.settings.wifi.tether.WifiTetherBasePreferenceController; Loading @@ -59,10 +60,10 @@ import com.android.settingslib.search.SearchIndexable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicReference; /** * Displays preferences for Tethering. * TODO(b/147322704): Use TetherEnabler in this fragment to manage tethering switch on/off. * Displays preferences for all Tethering options. * TODO(b/147323306): Add tether option preferences into this fragment after controllers created. */ @SearchIndexable Loading Loading @@ -96,6 +97,7 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment private WifiManager mWifiManager; private boolean mRestartWifiApAfterConfigChange; private final AtomicReference<BluetoothPan> mBluetoothPan = new AtomicReference<>(); private WifiTetherSSIDPreferenceController mSSIDPreferenceController; private WifiTetherPasswordPreferenceController mPasswordPreferenceController; Loading @@ -103,8 +105,8 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment private WifiTetherSecurityPreferenceController mSecurityPreferenceController; private PreferenceGroup mWifiTetherGroup; private SharedPreferences mSharedPreferences; private ConnectivityManager mConnectivityManager; private boolean mWifiTetherChosen; private TetherEnabler mTetherEnabler; private final BroadcastReceiver mTetherChangeReceiver = new BroadcastReceiver() { @Override Loading @@ -118,19 +120,30 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_DISABLED && mRestartWifiApAfterConfigChange) { mRestartWifiApAfterConfigChange = false; startTether(); mTetherEnabler.startTethering(TETHERING_WIFI); } } else if (TextUtils.equals(action, WIFI_AP_STATE_CHANGED_ACTION)) { int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, 0); if (state == WifiManager.WIFI_AP_STATE_DISABLED && mRestartWifiApAfterConfigChange) { mRestartWifiApAfterConfigChange = false; startTether(); mTetherEnabler.startTethering(TETHERING_WIFI); } } } }; private final BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { mBluetoothPan.set((BluetoothPan) proxy); } public void onServiceDisconnected(int profile) { mBluetoothPan.set(null); } }; @Override public int getMetricsCategory() { return SettingsEnums.TETHER; Loading @@ -144,8 +157,6 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment public void onAttach(Context context) { super.onAttach(context); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); mSharedPreferences = context.getSharedPreferences(TetherEnabler.SHARED_PREF, Context.MODE_PRIVATE); Loading Loading @@ -181,6 +192,27 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment // TODO(b/147325229): Hide advanced settings like security and ap band. } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (mUnavailable) { return; } // Assume we are in a SettingsActivity. This is only safe because we currently use // SettingsActivity as base for all preference fragments. final SettingsActivity activity = (SettingsActivity) getActivity(); BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); if (adapter != null) { adapter.getProfileProxy(activity.getApplicationContext(), mProfileServiceListener, BluetoothProfile.PAN); } final SwitchBar switchBar = activity.getSwitchBar(); mTetherEnabler = new TetherEnabler(activity, new SwitchBarController(switchBar), mBluetoothPan); getSettingsLifecycle().addObserver(mTetherEnabler); switchBar.show(); } @Override public void onStart() { super.onStart(); Loading Loading @@ -297,8 +329,7 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment Log.d(TAG, "Wifi AP config changed while enabled, stop and restart"); } mRestartWifiApAfterConfigChange = true; // TODO(b/147322704): Use TethetEnabler to stop tethering. mConnectivityManager.stopTethering(TETHERING_WIFI); mTetherEnabler.stopTethering(TETHERING_WIFI); } if (controller instanceof WifiTetherSecurityPreferenceController) { Loading Loading @@ -335,23 +366,6 @@ public final class AllInOneTetherSettings extends RestrictedDashboardFragment } } private void startTether() { // TODO(b/147322704): Use TetherEnabler to start tethering. if (mWifiManager.isWifiApEnabled()) { return; } mConnectivityManager.startTethering(ConnectivityManager.TETHERING_WIFI, true /*showProvisioningUi*/, new ConnectivityManager.OnStartTetheringCallback() { @Override public void onTetheringFailed() { super.onTetheringFailed(); // Do nothing. There is no UI to update at this point. } }, new Handler(Looper.getMainLooper())); } private void reConfigInitialExpandedChildCount() { getPreferenceScreen().setInitialExpandedChildrenCount(getInitialExpandedChildCount()); } Loading
src/com/android/settings/network/BluetoothTetherPreferenceController.java +1 −2 Original line number Diff line number Diff line Loading @@ -47,8 +47,7 @@ public final class BluetoothTetherPreferenceController extends AbstractPreferenc private static final String TAG = "BluetoothTetherPreferenceController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String PREF_KEY = "enable_bluetooth_tethering"; public static final String PREF_KEY = "enable_bluetooth_tethering"; private final ConnectivityManager mCm; private int mBluetoothState; private Preference mPreference; Loading
src/com/android/settings/network/TetherEnabler.java +125 −42 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.settings.datausage.DataSaverBackend; import com.android.settings.widget.SwitchWidgetController; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicReference; Loading Loading @@ -78,14 +79,7 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang private final Context mContext; @VisibleForTesting final ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback = new ConnectivityManager.OnStartTetheringCallback() { @Override public void onTetheringFailed() { super.onTetheringFailed(); mSwitchWidgetController.setChecked(false); } }; ConnectivityManager.OnStartTetheringCallback mOnStartTetheringCallback; private final AtomicReference<BluetoothPan> mBluetoothPan; private final SharedPreferences mSharedPreferences; private boolean mBluetoothEnableForTether; Loading @@ -110,11 +104,15 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang mDataSaverBackend.addListener(this); mSwitchWidgetController.setListener(this); mSwitchWidgetController.startListening(); IntentFilter filter = new IntentFilter(ConnectivityManager.ACTION_TETHER_STATE_CHANGED); final IntentFilter filter = new IntentFilter( ConnectivityManager.ACTION_TETHER_STATE_CHANGED); filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); mContext.registerReceiver(mTetherChangeReceiver, filter); mSwitchWidgetController.setChecked(isTethering()); setSwitchWidgetEnabled(true); mOnStartTetheringCallback = new OnStartTetheringCallback(this); updateState(); } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) Loading @@ -134,8 +132,14 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang mContext.unregisterReceiver(mTetherChangeReceiver); } private void setSwitchWidgetEnabled(boolean enabled) { mSwitchWidgetController.setEnabled(enabled && !mDataSaverEnabled); private void updateState() { mSwitchWidgetController.setChecked(isTethering()); mSwitchWidgetController.setEnabled(!mDataSaverEnabled); } private void updateState(String[] tethered) { mSwitchWidgetController.setChecked(isTethering(tethered)); mSwitchWidgetController.setEnabled(!mDataSaverEnabled); } private boolean isTethering() { Loading @@ -148,6 +152,10 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang return true; } if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) { return true; } final BluetoothPan pan = mBluetoothPan.get(); return pan != null && pan.isTetheringOn(); Loading @@ -155,29 +163,39 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang @Override public boolean onSwitchToggled(boolean isChecked) { if (isChecked) { if (isChecked && !isTethering()) { startTether(); } else { } if (!isChecked && isTethering()) { stopTether(); } return true; } @VisibleForTesting void stopTether() { private void stopTether() { // Wi-Fi tether is selected by default. if (mSharedPreferences.getBoolean(WIFI_TETHER_KEY, true)) { mConnectivityManager.stopTethering(TETHERING_WIFI); stopTethering(TETHERING_WIFI); } if (mSharedPreferences.getBoolean(USB_TETHER_KEY, false)) { mConnectivityManager.stopTethering(TETHERING_USB); stopTethering(TETHERING_USB); } if (mSharedPreferences.getBoolean(BLUETOOTH_TETHER_KEY, false)) { mConnectivityManager.stopTethering(TETHERING_BLUETOOTH); stopTethering(TETHERING_BLUETOOTH); } } /** * Use this method to stop a single choice of tethering. * * @param choice The choice of tethering to stop. */ public void stopTethering(int choice) { mConnectivityManager.stopTethering(choice); } @VisibleForTesting Loading @@ -197,8 +215,16 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang } } @VisibleForTesting void startTethering(int choice) { /** * Use this method to start a single choice of tethering. * For bluetooth tethering, it will first turn on bluetooth if bluetooth is off. * For Wi-Fi tethering, it will be no-op if Wi-Fi tethering already active. * * @param choice The choice of tethering to start. */ public void startTethering(int choice) { mSwitchWidgetController.setEnabled(false); if (choice == TETHERING_WIFI && mWifiManager.isWifiApEnabled()) { if (DEBUG) { Log.d(TAG, "Wifi tether already active!"); Loading @@ -224,15 +250,32 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang private final BroadcastReceiver mTetherChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); final String action = intent.getAction(); ArrayList<String> active = null; boolean shouldUpdateState = false; if (TextUtils.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED, action)) { ArrayList<String> active = intent.getStringArrayListExtra( ConnectivityManager.EXTRA_ACTIVE_TETHER); mSwitchWidgetController.setChecked( isTethering(active.toArray(new String[active.size()]))); active = intent.getStringArrayListExtra(ConnectivityManager.EXTRA_ACTIVE_TETHER); shouldUpdateState = true; } else if (TextUtils.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION, action)) { shouldUpdateState = handleWifiApStateChanged(intent.getIntExtra( WifiManager.EXTRA_WIFI_AP_STATE, WifiManager.WIFI_AP_STATE_FAILED)); } else if (TextUtils.equals(BluetoothAdapter.ACTION_STATE_CHANGED, action)) { switch (intent .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)) { shouldUpdateState = handleBluetoothStateChanged(intent .getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR)); } if (shouldUpdateState) { if (active != null) { updateState(active.toArray(new String[0])); } else { updateState(); } } } }; private boolean handleBluetoothStateChanged(int state) { switch (state) { case BluetoothAdapter.STATE_ON: if (mBluetoothEnableForTether) { startTethering(TETHERING_BLUETOOTH); Loading @@ -242,18 +285,32 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang // Fall through. case BluetoothAdapter.ERROR: mBluetoothEnableForTether = false; break; return true; default: // ignore transition states // Return false for transition states. return false; } } private boolean handleWifiApStateChanged(int state) { switch (state) { case WifiManager.WIFI_AP_STATE_FAILED: Log.e(TAG, "Wifi AP is failed!"); // fall through case WifiManager.WIFI_AP_STATE_ENABLED: // fall through case WifiManager.WIFI_AP_STATE_DISABLED: return true; default: // return false for transition state return false; } } }; @Override public void onDataSaverChanged(boolean isDataSaving) { mDataSaverEnabled = isDataSaving; setSwitchWidgetEnabled(!isDataSaving); mSwitchWidgetController.setEnabled(!isDataSaving); } @Override Loading Loading @@ -291,4 +348,30 @@ public final class TetherEnabler implements SwitchWidgetController.OnSwitchChang } } } private static final class OnStartTetheringCallback extends ConnectivityManager.OnStartTetheringCallback { final WeakReference<TetherEnabler> mTetherEnabler; OnStartTetheringCallback(TetherEnabler enabler) { mTetherEnabler = new WeakReference<>(enabler); } @Override public void onTetheringStarted() { update(); } @Override public void onTetheringFailed() { update(); } private void update() { TetherEnabler enabler = mTetherEnabler.get(); if (enabler != null) { enabler.updateState(); } } } }
src/com/android/settings/network/UsbTetherPreferenceController.java +1 −2 Original line number Diff line number Diff line Loading @@ -49,8 +49,7 @@ public final class UsbTetherPreferenceController extends AbstractPreferenceContr private static final String TAG = "UsbTetherPrefController"; private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); @VisibleForTesting static final String PREF_KEY = "enable_usb_tethering"; public static final String PREF_KEY = "enable_usb_tethering"; private final ConnectivityManager mCm; private boolean mUsbConnected; Loading
tests/robotests/src/com/android/settings/network/TetherEnablerTest.java +3 −1 Original line number Diff line number Diff line Loading @@ -109,8 +109,10 @@ public class TetherEnablerTest { @Test public void startTether_fail_resetSwitchBar() { when(mNetworkPolicyManager.getRestrictBackground()).thenReturn(false); mEnabler.onStart(); mEnabler.startTether(); when(mConnectivityManager.getTetheredIfaces()).thenReturn(new String[0]); mEnabler.mOnStartTetheringCallback.onTetheringFailed(); assertThat(mSwitchBar.isChecked()).isFalse(); Loading