diff --git a/src/com/android/settings/development/WirelessDebuggingEnabler.java b/src/com/android/settings/development/WirelessDebuggingEnabler.java index 51b81f61079..8fec233102b 100644 --- a/src/com/android/settings/development/WirelessDebuggingEnabler.java +++ b/src/com/android/settings/development/WirelessDebuggingEnabler.java @@ -24,7 +24,9 @@ import android.os.Handler; import android.os.Looper; import android.provider.Settings; import android.util.Log; +import android.widget.Toast; +import com.android.settings.R; import com.android.settings.widget.SwitchWidgetController; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.LifecycleObserver; @@ -121,6 +123,15 @@ public class WirelessDebuggingEnabler implements SwitchWidgetController.OnSwitch @Override public boolean onSwitchToggled(boolean isChecked) { + if (isChecked && !WirelessDebuggingPreferenceController.isWifiConnected(mContext)) { + // No connected Wi-Fi network. Reset the switch to off. + Toast.makeText( + mContext, R.string.adb_wireless_no_network_msg, Toast.LENGTH_LONG) + .show(); + mSwitchWidget.setChecked(false); + return false; + } + writeAdbWifiSetting(isChecked); return true; } diff --git a/src/com/android/settings/development/WirelessDebuggingPreferenceController.java b/src/com/android/settings/development/WirelessDebuggingPreferenceController.java index 81575d2334f..55fd074cc10 100644 --- a/src/com/android/settings/development/WirelessDebuggingPreferenceController.java +++ b/src/com/android/settings/development/WirelessDebuggingPreferenceController.java @@ -19,6 +19,8 @@ import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.debug.IAdbManager; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; import android.net.Uri; import android.os.Handler; import android.os.Looper; @@ -26,10 +28,12 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.provider.Settings; import android.util.Log; +import android.widget.Toast; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; +import com.android.settings.R; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.widget.MasterSwitchPreference; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -131,9 +135,29 @@ public class WirelessDebuggingPreferenceController extends DeveloperOptionsPrefe ((MasterSwitchPreference) preference).setChecked(enabled); } + static boolean isWifiConnected(Context context) { + ConnectivityManager cm = (ConnectivityManager) context.getSystemService( + Context.CONNECTIVITY_SERVICE); + if (cm != null) { + NetworkInfo info = cm.getActiveNetworkInfo(); + if (info != null && info.isConnected()) { + return info.getType() == ConnectivityManager.TYPE_WIFI; + } + } + return false; + } + @Override public boolean onPreferenceChange(Preference preference, Object newValue) { final boolean enabled = (Boolean) newValue; + if (enabled && !isWifiConnected(mContext)) { + // Cannot enable ADB over Wi-Fi if we're not connected to wifi. + Toast.makeText( + mContext, R.string.adb_wireless_no_network_msg, Toast.LENGTH_LONG) + .show(); + return false; + } + Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ADB_WIFI_ENABLED, enabled ? AdbPreferenceController.ADB_SETTING_ON diff --git a/tests/robotests/src/com/android/settings/development/WirelessDebuggingEnablerTest.java b/tests/robotests/src/com/android/settings/development/WirelessDebuggingEnablerTest.java index 56e898f8880..1baf4836a79 100644 --- a/tests/robotests/src/com/android/settings/development/WirelessDebuggingEnablerTest.java +++ b/tests/robotests/src/com/android/settings/development/WirelessDebuggingEnablerTest.java @@ -28,10 +28,12 @@ import android.provider.Settings.Global; import androidx.lifecycle.LifecycleOwner; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.testutils.shadow.ShadowWirelessDebuggingPreferenceController; import com.android.settings.widget.SwitchBar; import com.android.settings.widget.SwitchBarController; import com.android.settingslib.core.lifecycle.Lifecycle; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -43,7 +45,7 @@ import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowUtils.class) +@Config(shadows = {ShadowUtils.class, ShadowWirelessDebuggingPreferenceController.class}) public class WirelessDebuggingEnablerTest { @Mock @@ -66,6 +68,11 @@ public class WirelessDebuggingEnablerTest { mContext, new SwitchBarController(mSwitchBar), mListener, mLifecycle)); } + @After + public void tearDown() { + ShadowWirelessDebuggingPreferenceController.reset(); + } + @Test public void onCreation_shouldShowSwitchBar() { verify(mSwitchBar).show(); @@ -120,7 +127,8 @@ public class WirelessDebuggingEnablerTest { } @Test - public void onSwitchToggled_true_shouldSetAdbWifiEnabledTrue() { + public void onSwitchToggled_true_wifiConnected_shouldSetAdbWifiEnabledTrue() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(true); Global.putInt(mContext.getContentResolver(), Global.ADB_WIFI_ENABLED, 0 /* setting disabled */); mWirelessDebuggingEnabler.onResume(); @@ -132,11 +140,27 @@ public class WirelessDebuggingEnablerTest { assertThat(Global.getInt(mContext.getContentResolver(), Global.ADB_WIFI_ENABLED, -1)).isEqualTo(1); - // Should also get a callback } @Test - public void onSwitchToggled_false_shouldSetAdbWifiEnabledFalse() { + public void onSwitchToggled_true_wifiNotConnected_shouldSetAdbWifiEnabledFalse() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(false); + Global.putInt(mContext.getContentResolver(), + Global.ADB_WIFI_ENABLED, 0 /* setting disabled */); + mWirelessDebuggingEnabler.onResume(); + + verify(mSwitchBar).setChecked(false); + verify(mListener).onEnabled(false); + + mWirelessDebuggingEnabler.onSwitchToggled(true); + + assertThat(Global.getInt(mContext.getContentResolver(), + Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); + } + + @Test + public void onSwitchToggled_false_wifiConnected_shouldSetAdbWifiEnabledFalse() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(true); Global.putInt(mContext.getContentResolver(), Global.ADB_WIFI_ENABLED, 1 /* setting disabled */); mWirelessDebuggingEnabler.onResume(); @@ -147,7 +171,22 @@ public class WirelessDebuggingEnablerTest { mWirelessDebuggingEnabler.onSwitchToggled(false); assertThat(Global.getInt(mContext.getContentResolver(), - Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); - // Should also get a callback + Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); + } + + @Test + public void onSwitchToggled_false_wifiNotConnected_shouldSetAdbWifiEnabledFalse() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(false); + Global.putInt(mContext.getContentResolver(), + Global.ADB_WIFI_ENABLED, 1 /* setting disabled */); + mWirelessDebuggingEnabler.onResume(); + + verify(mSwitchBar).setChecked(true); + verify(mListener).onEnabled(true); + + mWirelessDebuggingEnabler.onSwitchToggled(false); + + assertThat(Global.getInt(mContext.getContentResolver(), + Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); } } diff --git a/tests/robotests/src/com/android/settings/development/WirelessDebuggingPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/WirelessDebuggingPreferenceControllerTest.java index f755ec416dd..da689b7b946 100644 --- a/tests/robotests/src/com/android/settings/development/WirelessDebuggingPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/WirelessDebuggingPreferenceControllerTest.java @@ -32,6 +32,7 @@ import androidx.lifecycle.LifecycleOwner; import androidx.preference.PreferenceScreen; import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.testutils.shadow.ShadowWirelessDebuggingPreferenceController; import com.android.settings.widget.MasterSwitchPreference; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -47,7 +48,7 @@ import org.robolectric.annotation.Config; import org.robolectric.util.ReflectionHelpers; @RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowUtils.class) +@Config(shadows = {ShadowUtils.class, ShadowWirelessDebuggingPreferenceController.class}) public class WirelessDebuggingPreferenceControllerTest { @Mock @@ -75,10 +76,12 @@ public class WirelessDebuggingPreferenceControllerTest { mController = spy(new WirelessDebuggingPreferenceController(mContext, mLifecycle)); ReflectionHelpers.setField(mController, "mAdbManager", mAdbManager); when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); + Global.putInt(mContentResolver, Global.ADB_WIFI_ENABLED, 0); } @After public void tearDown() { + ShadowWirelessDebuggingPreferenceController.reset(); } @Test @@ -112,9 +115,35 @@ public class WirelessDebuggingPreferenceControllerTest { } @Test - public void onPreferenceChange_turnOn_adbWifiEnabledTrue() { + public void onPreferenceChange_turnOn_wifiConnected_adbWifiEnabledTrue() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(true); mController.onPreferenceChange(null, true); assertThat(Global.getInt(mContentResolver, Global.ADB_WIFI_ENABLED, -1)).isEqualTo(1); } + + @Test + public void onPreferenceChange_turnOff_wifiConnected_adbWifiEnabledFalse() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(true); + mController.onPreferenceChange(null, false); + + assertThat(Global.getInt(mContentResolver, Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); + } + + @Test + public void onPreferenceChange_turnOn_wifiNotConnected_adbWifiEnabledFalse() { + // Should not be able to enable wifi debugging without being connected to a wifi network + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(false); + mController.onPreferenceChange(null, true); + + assertThat(Global.getInt(mContentResolver, Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); + } + + @Test + public void onPreferenceChange_turnOff_wifiNotConnected_adbWifiEnabledFalse() { + ShadowWirelessDebuggingPreferenceController.setIsWifiConnected(false); + mController.onPreferenceChange(null, false); + + assertThat(Global.getInt(mContentResolver, Global.ADB_WIFI_ENABLED, -1)).isEqualTo(0); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWirelessDebuggingPreferenceController.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWirelessDebuggingPreferenceController.java new file mode 100644 index 00000000000..49641b0005c --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowWirelessDebuggingPreferenceController.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import android.content.Context; + +import com.android.settings.development.WirelessDebuggingPreferenceController; + +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; + +@Implements(WirelessDebuggingPreferenceController.class) +public class ShadowWirelessDebuggingPreferenceController { + private static boolean sIsWifiConnected; + + public static void setIsWifiConnected(boolean isConnected) { + sIsWifiConnected = isConnected; + } + + public static void reset() { + sIsWifiConnected = false; + } + + @Implementation + protected static boolean isWifiConnected(Context context) { + return sIsWifiConnected; + } +}