From 42405603c7fd8da84e43cdcdc43f23d93f0fd56a Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 14 Mar 2018 20:54:53 +0900 Subject: [PATCH] Move the Private DNS dialog back to the top level. Bug: 64133961 Fixes: 74844869 Test: visual test and interaction also updated tests and checked they pass Change-Id: I7c8d50e5941c2a7dd46014932bdace14dc222c80 --- res/xml/network_and_internet.xml | 34 +++-- .../network/NetworkDashboardFragment.java | 9 +- ...va => PrivateDnsModeDialogPreference.java} | 108 +++++++------- ...va => PrivateDnsPreferenceController.java} | 35 +++-- .../network/VpnPreferenceController.java | 2 - .../network/NetworkDashboardFragmentTest.java | 2 - .../network/PrivateDnsMenuControllerTest.java | 65 --------- .../PrivateDnsModeDialogFragmentTest.java | 117 --------------- .../PrivateDnsModeDialogPreferenceTest.java | 137 ++++++++++++++++++ 9 files changed, 235 insertions(+), 274 deletions(-) rename src/com/android/settings/network/{PrivateDnsModeDialogFragment.java => PrivateDnsModeDialogPreference.java} (71%) rename src/com/android/settings/network/{PrivateDnsMenuController.java => PrivateDnsPreferenceController.java} (50%) delete mode 100644 tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java create mode 100644 tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java diff --git a/res/xml/network_and_internet.xml b/res/xml/network_and_internet.xml index a28b1e6b268..ee99998d293 100644 --- a/res/xml/network_and_internet.xml +++ b/res/xml/network_and_internet.xml @@ -18,7 +18,8 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="network_and_internet_screen" - android:title="@string/network_dashboard_title"> + android:title="@string/network_dashboard_title" + settings:initialExpandedChildrenCount="5"> - - @@ -88,4 +80,22 @@ android:key="proxy_settings" android:title="@string/proxy_settings_title" /> - \ No newline at end of file + + + + + diff --git a/src/com/android/settings/network/NetworkDashboardFragment.java b/src/com/android/settings/network/NetworkDashboardFragment.java index 7d8ea18c7a4..955c50390ee 100644 --- a/src/com/android/settings/network/NetworkDashboardFragment.java +++ b/src/com/android/settings/network/NetworkDashboardFragment.java @@ -49,10 +49,8 @@ public class NetworkDashboardFragment extends DashboardFragment implements private static final String TAG = "NetworkDashboardFrag"; private static final int MENU_NETWORK_RESET = Menu.FIRST; - private static final int MENU_PRIVATE_DNS = Menu.FIRST + 1; private NetworkResetActionMenuController mNetworkResetController; - private PrivateDnsMenuController mPrivateDnsMenuController; @Override public int getMetricsCategory() { @@ -73,8 +71,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements public void onAttach(Context context) { super.onAttach(context); mNetworkResetController = new NetworkResetActionMenuController(context, MENU_NETWORK_RESET); - mPrivateDnsMenuController = new PrivateDnsMenuController(getFragmentManager(), - MENU_PRIVATE_DNS); } @Override @@ -86,7 +82,6 @@ public class NetworkDashboardFragment extends DashboardFragment implements public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); mNetworkResetController.buildMenuItem(menu); - mPrivateDnsMenuController.buildMenuItem(menu); } @Override @@ -109,6 +104,8 @@ public class NetworkDashboardFragment extends DashboardFragment implements new MobileNetworkPreferenceController(context); final VpnPreferenceController vpnPreferenceController = new VpnPreferenceController(context); + final PrivateDnsPreferenceController privateDnsPreferenceController = + new PrivateDnsPreferenceController(context); if (lifecycle != null) { lifecycle.addObserver(airplaneModePreferenceController); @@ -116,6 +113,7 @@ public class NetworkDashboardFragment extends DashboardFragment implements lifecycle.addObserver(wifiPreferenceController); lifecycle.addObserver(mobileNetworkPreferenceController); lifecycle.addObserver(vpnPreferenceController); + lifecycle.addObserver(privateDnsPreferenceController); } final List controllers = new ArrayList<>(); @@ -126,6 +124,7 @@ public class NetworkDashboardFragment extends DashboardFragment implements controllers.add(new ProxyPreferenceController(context)); controllers.add(mobilePlanPreferenceController); controllers.add(wifiPreferenceController); + controllers.add(privateDnsPreferenceController); return controllers; } diff --git a/src/com/android/settings/network/PrivateDnsModeDialogFragment.java b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java similarity index 71% rename from src/com/android/settings/network/PrivateDnsModeDialogFragment.java rename to src/com/android/settings/network/PrivateDnsModeDialogPreference.java index 00950c3adc7..3b09cc2e560 100644 --- a/src/com/android/settings/network/PrivateDnsModeDialogFragment.java +++ b/src/com/android/settings/network/PrivateDnsModeDialogPreference.java @@ -20,19 +20,18 @@ import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; import android.app.AlertDialog; -import android.app.Dialog; -import android.app.FragmentManager; +import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.os.Bundle; import android.provider.Settings; import android.support.annotation.VisibleForTesting; import android.text.Editable; import android.text.TextWatcher; import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; +import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; @@ -41,8 +40,9 @@ import android.widget.TextView; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; -import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.utils.AnnotationSpan; +import com.android.settingslib.CustomDialogPreference; import com.android.settingslib.HelpUtils; import java.util.HashMap; @@ -51,7 +51,7 @@ import java.util.Map; /** * Dialog to set the private dns */ -public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment implements +public class PrivateDnsModeDialogPreference extends CustomDialogPreference implements DialogInterface.OnClickListener, RadioGroup.OnCheckedChangeListener, TextWatcher { public static final String ANNOTATION_URL = "url"; @@ -77,41 +77,44 @@ public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment imp @VisibleForTesting RadioGroup mRadioGroup; @VisibleForTesting - Button mSaveButton; - @VisibleForTesting String mMode; - public static void show(FragmentManager fragmentManager) { - if (fragmentManager.findFragmentByTag(TAG) == null) { - final PrivateDnsModeDialogFragment fragment = new PrivateDnsModeDialogFragment(); - fragment.show(fragmentManager, TAG); - } + public PrivateDnsModeDialogPreference(Context context) { + super(context); } + public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public PrivateDnsModeDialogPreference(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + private final AnnotationSpan.LinkInfo mUrlLinkInfo = new AnnotationSpan.LinkInfo( + ANNOTATION_URL, (widget) -> { + final Context context = widget.getContext(); + final Intent intent = HelpUtils.getHelpIntent(context, + context.getString(R.string.help_uri_private_dns), + context.getClass().getName()); + if (intent != null) { + try { + widget.startActivityForResult(intent, 0); + } catch (ActivityNotFoundException e) { + Log.w(TAG, "Activity was not found for intent, " + intent.toString()); + } + } + }); + @Override - public Dialog onCreateDialog(Bundle savedInstanceState) { + protected void onBindDialogView(View view) { final Context context = getContext(); - - final AlertDialog dialog = new AlertDialog.Builder(context) - .setTitle(R.string.select_private_dns_configuration_title) - .setView(buildPrivateDnsView(context)) - .setPositiveButton(R.string.save, this) - .setNegativeButton(R.string.dlg_cancel, null) - .create(); - - dialog.setOnShowListener(dialogInterface -> { - mSaveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE); - updateDialogInfo(); - }); - return dialog; - } - - private View buildPrivateDnsView(final Context context) { final ContentResolver contentResolver = context.getContentResolver(); - mMode = Settings.Global.getString(contentResolver, MODE_KEY); - final View view = LayoutInflater.from(context).inflate(R.layout.private_dns_mode_dialog, - null); - mEditText = view.findViewById(R.id.private_dns_mode_provider_hostname); mEditText.addTextChangedListener(this); mEditText.setText(Settings.Global.getString(contentResolver, HOSTNAME_KEY)); @@ -131,26 +134,20 @@ public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment imp helpTextView.setText(AnnotationSpan.linkify( context.getText(R.string.private_dns_help_message), linkInfo)); } - - return view; } @Override public void onClick(DialogInterface dialog, int which) { + final Context context = getContext(); if (mMode.equals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME)) { // Only clickable if hostname is valid, so we could save it safely - Settings.Global.putString(getContext().getContentResolver(), HOSTNAME_KEY, + Settings.Global.putString(context.getContentResolver(), HOSTNAME_KEY, mEditText.getText().toString()); } - mMetricsFeatureProvider.action(getContext(), + FeatureFactory.getFactory(context).getMetricsFeatureProvider().action(context, MetricsProto.MetricsEvent.ACTION_PRIVATE_DNS_MODE, mMode); - Settings.Global.putString(getContext().getContentResolver(), MODE_KEY, mMode); - } - - @Override - public int getMetricsCategory() { - return MetricsProto.MetricsEvent.DIALOG_PRIVATE_DNS; + Settings.Global.putString(context.getContentResolver(), MODE_KEY, mMode); } @Override @@ -179,9 +176,7 @@ public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment imp @Override public void afterTextChanged(Editable s) { - if (mSaveButton != null) { - mSaveButton.setEnabled(isWeaklyValidatedHostname(mEditText.getText().toString())); - } + updateDialogInfo(); } private boolean isWeaklyValidatedHostname(String hostname) { @@ -193,17 +188,24 @@ public class PrivateDnsModeDialogFragment extends InstrumentedDialogFragment imp return hostname.matches(WEAK_HOSTNAME_REGEX); } + private Button getSaveButton() { + final AlertDialog dialog = (AlertDialog) getDialog(); + if (dialog == null) { + return null; + } + return dialog.getButton(DialogInterface.BUTTON_POSITIVE); + } + private void updateDialogInfo() { final boolean modeProvider = PRIVATE_DNS_MODE_PROVIDER_HOSTNAME.equals(mMode); if (mEditText != null) { mEditText.setEnabled(modeProvider); } - if (mSaveButton != null) { - mSaveButton.setEnabled( - modeProvider - ? isWeaklyValidatedHostname(mEditText.getText().toString()) - : true); + final Button saveButton = getSaveButton(); + if (saveButton != null) { + saveButton.setEnabled(modeProvider + ? isWeaklyValidatedHostname(mEditText.getText().toString()) + : true); } } - } diff --git a/src/com/android/settings/network/PrivateDnsMenuController.java b/src/com/android/settings/network/PrivateDnsPreferenceController.java similarity index 50% rename from src/com/android/settings/network/PrivateDnsMenuController.java rename to src/com/android/settings/network/PrivateDnsPreferenceController.java index a8117755565..e3175300792 100644 --- a/src/com/android/settings/network/PrivateDnsMenuController.java +++ b/src/com/android/settings/network/PrivateDnsPreferenceController.java @@ -16,29 +16,28 @@ package com.android.settings.network; -import android.app.FragmentManager; -import android.view.Menu; -import android.view.MenuItem; +import android.content.Context; import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.core.PreferenceControllerMixin; +import com.android.settingslib.core.lifecycle.LifecycleObserver; -public class PrivateDnsMenuController { - private final FragmentManager mFragmentManager; - private final int mMenuId; +public class PrivateDnsPreferenceController extends BasePreferenceController + implements PreferenceControllerMixin, LifecycleObserver { + private static final String KEY_PRIVATE_DNS_SETTINGS = "private_dns_settings"; - public PrivateDnsMenuController(FragmentManager fragmentManager, int menuId) { - mFragmentManager = fragmentManager; - mMenuId = menuId; + public PrivateDnsPreferenceController(Context context) { + super(context, KEY_PRIVATE_DNS_SETTINGS); } - public void buildMenuItem(Menu menu) { - if (menu != null) { - MenuItem item = menu.add(0 /* groupId */, mMenuId, 0 /* order */, - R.string.select_private_dns_configuration_title); - item.setOnMenuItemClickListener(target -> { - PrivateDnsModeDialogFragment.show(mFragmentManager); - return true; - }); - } + @Override + public String getPreferenceKey() { + return KEY_PRIVATE_DNS_SETTINGS; + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; } } diff --git a/src/com/android/settings/network/VpnPreferenceController.java b/src/com/android/settings/network/VpnPreferenceController.java index 95513e08624..c4ecf4f7111 100644 --- a/src/com/android/settings/network/VpnPreferenceController.java +++ b/src/com/android/settings/network/VpnPreferenceController.java @@ -180,13 +180,11 @@ public class VpnPreferenceController extends AbstractPreferenceController mNetworkCallback = new ConnectivityManager.NetworkCallback() { @Override public void onAvailable(Network network) { - Log.d(TAG, "onAvailable " + network.netId); updateSummary(); } @Override public void onLost(Network network) { - Log.d(TAG, "onLost " + network.netId); updateSummary(); } }; diff --git a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java index 19c9f872eb6..51722e5e55a 100644 --- a/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java +++ b/tests/robotests/src/com/android/settings/network/NetworkDashboardFragmentTest.java @@ -76,9 +76,7 @@ public class NetworkDashboardFragmentTest { public void testPrepareActionBar_networkResetShouldBeCreated() { final NetworkResetActionMenuController resetController = mock(NetworkResetActionMenuController.class); - final PrivateDnsMenuController privateDnsController = mock(PrivateDnsMenuController.class); ReflectionHelpers.setField(mFragment, "mNetworkResetController", resetController); - ReflectionHelpers.setField(mFragment, "mPrivateDnsMenuController", privateDnsController); mFragment.onCreateOptionsMenu(null, null); diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java deleted file mode 100644 index fa824d6c155..00000000000 --- a/tests/robotests/src/com/android/settings/network/PrivateDnsMenuControllerTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.network; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.FragmentManager; -import android.view.Menu; -import android.view.MenuItem; - -import com.android.settings.R; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -@RunWith(SettingsRobolectricTestRunner.class) -public class PrivateDnsMenuControllerTest { - private static final int MENU_ID = 0; - - private PrivateDnsMenuController mController; - @Mock - private Menu mMenu; - @Mock - private MenuItem mMenuItem; - @Mock - private FragmentManager mFragmentManager; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mController = new PrivateDnsMenuController(mFragmentManager, MENU_ID); - when(mMenu.add(anyInt(), anyInt(), anyInt(), anyInt())).thenReturn(mMenuItem); - } - - @Test - public void buildMenuItem_available_shouldAddToMenu() { - mController.buildMenuItem(mMenu); - - verify(mMenu).add(0 /* groupId */, MENU_ID, 0 /* order */, - R.string.select_private_dns_configuration_title); - verify(mMenuItem).setOnMenuItemClickListener(any(MenuItem.OnMenuItemClickListener.class)); - } -} diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java deleted file mode 100644 index d490968ca62..00000000000 --- a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogFragmentTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.network; - -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; -import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; - -import android.content.Context; -import android.provider.Settings; -import android.widget.Button; - -import com.android.settings.R; -import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.testutils.shadow.ShadowHelpUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = ShadowHelpUtils.class) -public class PrivateDnsModeDialogFragmentTest { - - private static final String HOST_NAME = "192.168.1.1"; - private static final String INVALID_HOST_NAME = "...,"; - - private Context mContext; - private PrivateDnsModeDialogFragment mFragment; - private Button mSaveButton; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = RuntimeEnvironment.application; - mSaveButton = new Button(mContext); - - mFragment = spy(new PrivateDnsModeDialogFragment()); - doReturn(mContext).when(mFragment).getContext(); - mFragment.onCreateDialog(null); - mFragment.mSaveButton = mSaveButton; - } - - @Test - public void testOnCheckedChanged_dnsModeOff_disableEditText() { - mFragment.onCheckedChanged(null, R.id.private_dns_mode_off); - - assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_OFF); - assertThat(mFragment.mEditText.isEnabled()).isFalse(); - } - - @Test - public void testOnCheckedChanged_dnsModeOpportunistic_disableEditText() { - mFragment.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); - - assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC); - assertThat(mFragment.mEditText.isEnabled()).isFalse(); - } - - @Test - public void testOnCheckedChanged_dnsModeProvider_enableEditText() { - mFragment.onCheckedChanged(null, R.id.private_dns_mode_provider); - - assertThat(mFragment.mMode).isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); - assertThat(mFragment.mEditText.isEnabled()).isTrue(); - } - - @Test - public void testOnCreateDialog_containsCorrectData() { - Settings.Global.putString(mContext.getContentResolver(), - PrivateDnsModeDialogFragment.MODE_KEY, PRIVATE_DNS_MODE_OPPORTUNISTIC); - Settings.Global.putString(mContext.getContentResolver(), - PrivateDnsModeDialogFragment.HOSTNAME_KEY, HOST_NAME); - - mFragment.onCreateDialog(null); - - assertThat(mFragment.mEditText.getText().toString()).isEqualTo(HOST_NAME); - assertThat(mFragment.mRadioGroup.getCheckedRadioButtonId()).isEqualTo( - R.id.private_dns_mode_opportunistic); - } - - @Test - public void testOnCheckedChanged_switchMode_saveButtonHasCorrectState() { - // Set invalid hostname - mFragment.mEditText.setText(INVALID_HOST_NAME); - - mFragment.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); - assertThat(mSaveButton.isEnabled()).isTrue(); - - mFragment.onCheckedChanged(null, R.id.private_dns_mode_provider); - assertThat(mSaveButton.isEnabled()).isFalse(); - - mFragment.onCheckedChanged(null, R.id.private_dns_mode_off); - assertThat(mSaveButton.isEnabled()).isTrue(); - } -} diff --git a/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java new file mode 100644 index 00000000000..8a60cf3a033 --- /dev/null +++ b/tests/robotests/src/com/android/settings/network/PrivateDnsModeDialogPreferenceTest.java @@ -0,0 +1,137 @@ +/* + * 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.network; + +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC; +import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.Context; +import android.provider.Settings; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; + +import com.android.settings.R; +import com.android.settingslib.CustomDialogPreference.CustomPreferenceDialogFragment; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.util.ReflectionHelpers; + +@RunWith(SettingsRobolectricTestRunner.class) +public class PrivateDnsModeDialogPreferenceTest { + + private static final String HOST_NAME = "dns.example.com"; + private static final String INVALID_HOST_NAME = "...,"; + + private PrivateDnsModeDialogPreference mPreference; + + private Context mContext; + private Button mSaveButton; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + mSaveButton = new Button(mContext); + + final CustomPreferenceDialogFragment fragment = mock(CustomPreferenceDialogFragment.class); + final AlertDialog dialog = mock(AlertDialog.class); + when(fragment.getDialog()).thenReturn(dialog); + when(dialog.getButton(anyInt())).thenReturn(mSaveButton); + + mPreference = new PrivateDnsModeDialogPreference(mContext); + ReflectionHelpers.setField(mPreference, "mFragment", fragment); + + final LayoutInflater inflater = LayoutInflater.from(mContext); + final View view = inflater.inflate(R.layout.private_dns_mode_dialog, + new LinearLayout(mContext), false); + + mPreference.onBindDialogView(view); + } + + @Test + public void testOnCheckedChanged_dnsModeOff_disableEditText() { + mPreference.onCheckedChanged(null, R.id.private_dns_mode_off); + + assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OFF); + assertThat(mPreference.mEditText.isEnabled()).isFalse(); + } + + @Test + public void testOnCheckedChanged_dnsModeOpportunistic_disableEditText() { + mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); + + assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_OPPORTUNISTIC); + assertThat(mPreference.mEditText.isEnabled()).isFalse(); + } + + @Test + public void testOnCheckedChanged_dnsModeProvider_enableEditText() { + mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); + + assertThat(mPreference.mMode).isEqualTo(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME); + assertThat(mPreference.mEditText.isEnabled()).isTrue(); + } + + @Test + public void testOnBindDialogView_containsCorrectData() { + Settings.Global.putString(mContext.getContentResolver(), + PrivateDnsModeDialogPreference.MODE_KEY, PRIVATE_DNS_MODE_OPPORTUNISTIC); + Settings.Global.putString(mContext.getContentResolver(), + PrivateDnsModeDialogPreference.HOSTNAME_KEY, HOST_NAME); + + final LayoutInflater inflater = LayoutInflater.from(mContext); + final View view = inflater.inflate(R.layout.private_dns_mode_dialog, + new LinearLayout(mContext), false); + mPreference.onBindDialogView(view); + + assertThat(mPreference.mEditText.getText().toString()).isEqualTo(HOST_NAME); + assertThat(mPreference.mRadioGroup.getCheckedRadioButtonId()).isEqualTo( + R.id.private_dns_mode_opportunistic); + } + + @Test + public void testOnCheckedChanged_switchMode_saveButtonHasCorrectState() { + // Set invalid hostname + mPreference.mEditText.setText(INVALID_HOST_NAME); + + mPreference.onCheckedChanged(null, R.id.private_dns_mode_opportunistic); + assertThat(mSaveButton.isEnabled()).isTrue(); + + mPreference.onCheckedChanged(null, R.id.private_dns_mode_provider); + assertThat(mSaveButton.isEnabled()).isFalse(); + + mPreference.onCheckedChanged(null, R.id.private_dns_mode_off); + assertThat(mSaveButton.isEnabled()).isTrue(); + } +}