diff --git a/res/values/strings.xml b/res/values/strings.xml index e5f4438192d..019c444fd13 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1634,6 +1634,8 @@ Use cellular data when Wi\u2011Fi has no Internet access. Data usage may apply. Add network + + Wi\u2011Fi preferences Wi\u2011Fi networks diff --git a/res/xml/wifi_configure_settings.xml b/res/xml/wifi_configure_settings.xml index a43ea87f9f8..1e047494721 100644 --- a/res/xml/wifi_configure_settings.xml +++ b/res/xml/wifi_configure_settings.xml @@ -17,11 +17,6 @@ - - - - - + + + + + + diff --git a/src/com/android/settings/wifi/ConfigureWifiSettings.java b/src/com/android/settings/wifi/ConfigureWifiSettings.java index e906090fffc..682662a31da 100644 --- a/src/com/android/settings/wifi/ConfigureWifiSettings.java +++ b/src/com/android/settings/wifi/ConfigureWifiSettings.java @@ -58,7 +58,6 @@ public class ConfigureWifiSettings extends DashboardFragment { mWifiManager = (WifiManager) getSystemService(WIFI_SERVICE); final List controllers = new ArrayList<>(); controllers.add(new WifiInfoPreferenceController(context, getLifecycle(), mWifiManager)); - controllers.add(new SavedNetworkPreferenceController(context, mWifiManager)); controllers.add(new CellularFallbackPreferenceController(context)); controllers.add(new AllowRecommendationPreferenceController(context)); controllers.add(new NotifyOpenNetworksPreferenceController(context, getLifecycle())); diff --git a/src/com/android/settings/wifi/LinkablePreference.java b/src/com/android/settings/wifi/LinkablePreference.java new file mode 100644 index 00000000000..6b1b87de438 --- /dev/null +++ b/src/com/android/settings/wifi/LinkablePreference.java @@ -0,0 +1,119 @@ +/* + * 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.wifi; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceViewHolder; +import android.text.Spannable; +import android.text.style.TextAppearanceSpan; +import android.util.AttributeSet; +import android.widget.TextView; +import com.android.settings.LinkifyUtils; + +/** + * A preference with a title that can have linkable content on click. + */ +public class LinkablePreference extends Preference { + + private LinkifyUtils.OnClickListener mClickListener; + private CharSequence mContentTitle; + private CharSequence mContentDescription; + + public LinkablePreference(Context ctx, AttributeSet attrs, int defStyle) { + super(ctx, attrs, defStyle); + setSelectable(false); + } + + public LinkablePreference(Context ctx, AttributeSet attrs) { + super(ctx, attrs); + setSelectable(false); + } + + public LinkablePreference(Context ctx) { + super(ctx); + setSelectable(false); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + + TextView textView = (TextView) view.findViewById(android.R.id.title); + if (textView == null || mContentTitle == null || mClickListener == null) { + return; + } + + textView.setSingleLine(false); + StringBuilder contentBuilder = new StringBuilder().append(mContentTitle); + if (mContentDescription != null) { + contentBuilder.append("\n\n"); + contentBuilder.append(mContentDescription); + } + + boolean linked = LinkifyUtils.linkify(textView, contentBuilder, mClickListener); + if (linked && mContentTitle != null) { + // Embolden and enlarge the title. + Spannable boldSpan = (Spannable) textView.getText(); + boldSpan.setSpan( + new TextAppearanceSpan( + getContext(), android.R.style.TextAppearance_Medium), + 0, + mContentTitle.length(), + Spannable.SPAN_INCLUSIVE_EXCLUSIVE); + textView.setText(boldSpan); + } + } + + /** + * Sets the linkable text for the Preference title. + * @param contentTitle text to set the Preference title. + * @param contentDescription description text to append underneath title, can be null. + * @param clickListener OnClickListener for the link portion of the text. + */ + public void setText( + CharSequence contentTitle, + @Nullable CharSequence contentDescription, + LinkifyUtils.OnClickListener clickListener) { + mContentTitle = contentTitle; + mContentDescription = contentDescription; + mClickListener = clickListener; + // sets the title so that the title TextView is not hidden in super.onBindViewHolder() + super.setTitle(contentTitle); + } + + /** + * Sets the title of the LinkablePreference. resets linkable text for reusability. + */ + @Override + public void setTitle(int titleResId) { + mContentTitle = null; + mContentDescription = null; + super.setTitle(titleResId); + } + + /** + * Sets the title of the LinkablePreference. resets linkable text for reusability. + */ + @Override + public void setTitle(CharSequence title) { + mContentTitle = null; + mContentDescription = null; + super.setTitle(title); + } +} diff --git a/src/com/android/settings/wifi/SavedNetworkPreferenceController.java b/src/com/android/settings/wifi/SavedNetworkPreferenceController.java deleted file mode 100644 index c3ad355a685..00000000000 --- a/src/com/android/settings/wifi/SavedNetworkPreferenceController.java +++ /dev/null @@ -1,51 +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.wifi; - -import android.content.Context; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; - -import com.android.settings.core.PreferenceController; - -import java.util.List; - -/** - * {@link PreferenceController} that opens saved network subsetting. - */ -public class SavedNetworkPreferenceController extends PreferenceController { - - private static final String KEY_SAVED_NETWORKS = "saved_networks"; - - private final WifiManager mWifiManager; - - public SavedNetworkPreferenceController(Context context, WifiManager wifiManager) { - super(context); - mWifiManager = wifiManager; - } - - @Override - public boolean isAvailable() { - final List config = mWifiManager.getConfiguredNetworks(); - return config != null && !config.isEmpty(); - } - - @Override - public String getPreferenceKey() { - return KEY_SAVED_NETWORKS; - } -} diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 73de575e95c..4fd93b53129 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -40,11 +40,10 @@ import android.os.HandlerThread; import android.os.Process; import android.provider.Settings; import android.support.v7.preference.Preference; +import android.support.v7.preference.PreferenceCategory; import android.support.v7.preference.PreferenceManager; import android.support.v7.preference.PreferenceViewHolder; -import android.text.Spannable; import android.text.TextUtils; -import android.text.style.TextAppearanceSpan; import android.util.Log; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; @@ -53,8 +52,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.TextView.BufferType; import android.widget.Toast; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -102,7 +99,6 @@ public class WifiSettings extends RestrictedSettingsFragment private static final int MENU_ID_FORGET = Menu.FIRST + 7; private static final int MENU_ID_MODIFY = Menu.FIRST + 8; private static final int MENU_ID_WRITE_NFC = Menu.FIRST + 9; - private static final int MENU_ID_CONFIGURE = Menu.FIRST + 10; public static final int WIFI_DIALOG_ID = 1; /* package */ static final int WPS_PBC_DIALOG_ID = 2; @@ -115,6 +111,9 @@ public class WifiSettings extends RestrictedSettingsFragment private static final String SAVED_WIFI_NFC_DIALOG_STATE = "wifi_nfc_dlg_state"; private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list"; + private static final String PREF_KEY_ACCESS_POINTS = "access_points"; + private static final String PREF_KEY_ADDITIONAL_SETTINGS = "additional_settings"; + private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks"; protected WifiManager mWifiManager; private WifiManager.ActionListener mConnectListener; @@ -152,7 +151,12 @@ public class WifiSettings extends RestrictedSettingsFragment private HandlerThread mBgThread; private AccessPointPreference.UserBadgeCache mUserBadgeCache; + + private PreferenceCategory mAccessPointsPreferenceCategory; + private PreferenceCategory mAdditionalSettingsPreferenceCategory; private Preference mAddPreference; + private Preference mSavedNetworksPreference; + private LinkablePreference mStatusMessagePreference; private MenuItem mScanMenuItem; @@ -177,9 +181,18 @@ public class WifiSettings extends RestrictedSettingsFragment getPreferenceManager().setPreferenceComparisonCallback( new PreferenceManager.SimplePreferenceComparisonCallback()); addPreferencesFromResource(R.xml.wifi_settings); - mAddPreference = new Preference(getContext()); + + mAccessPointsPreferenceCategory = + (PreferenceCategory) findPreference(PREF_KEY_ACCESS_POINTS); + mAdditionalSettingsPreferenceCategory = + (PreferenceCategory) findPreference(PREF_KEY_ADDITIONAL_SETTINGS); + mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS); + + Context prefContext = getPrefContext(); + mAddPreference = new Preference(prefContext); mAddPreference.setIcon(R.drawable.ic_menu_add_inset); mAddPreference.setTitle(R.string.wifi_add_network); + mStatusMessagePreference = new LinkablePreference(prefContext); mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager()); @@ -314,7 +327,6 @@ public class WifiSettings extends RestrictedSettingsFragment public void onResume() { final Activity activity = getActivity(); super.onResume(); - removePreference("dummy"); if (mWifiEnabler != null) { mWifiEnabler.resume(activity); } @@ -346,14 +358,13 @@ public class WifiSettings extends RestrictedSettingsFragment * @param menu */ void addOptionsMenuItems(Menu menu) { - final boolean wifiIsEnabled = mWifiTracker.isWifiEnabled(); - mScanMenuItem = menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.menu_stats_refresh); - mScanMenuItem.setEnabled(wifiIsEnabled) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced) .setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - menu.add(Menu.NONE, MENU_ID_CONFIGURE, 0, R.string.wifi_menu_configure) - .setIcon(R.drawable.ic_settings_24dp) + + final boolean wifiIsEnabled = mWifiTracker.isWifiEnabled(); + mScanMenuItem = menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.menu_stats_refresh) + .setIcon(com.android.internal.R.drawable.ic_menu_refresh); + mScanMenuItem.setEnabled(wifiIsEnabled) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); } @@ -424,18 +435,6 @@ public class WifiSettings extends RestrictedSettingsFragment null); } return true; - case MENU_ID_CONFIGURE: - if (getActivity() instanceof SettingsActivity) { - ((SettingsActivity) getActivity()).startPreferencePanel( - ConfigureWifiSettings.class.getCanonicalName(), null, - R.string.wifi_configure_titlebar, null, this, 0); - } else { - startFragment(this, ConfigureWifiSettings.class.getCanonicalName(), - R.string.wifi_configure_titlebar, -1 /* Do not request a results */, - null); - } - return true; - } return super.onOptionsItemSelected(item); } @@ -622,10 +621,10 @@ public class WifiSettings extends RestrictedSettingsFragment // Safeguard from some delayed event handling if (getActivity() == null) return; if (isUiRestricted()) { + mAccessPointsPreferenceCategory.removeAll(); if (!isUiRestrictedByOnlyAdmin()) { addMessagePreference(R.string.wifi_empty_list_user_restricted); } - getPreferenceScreen().removeAll(); return; } final int wifiState = mWifiManager.getWifiState(); @@ -638,7 +637,8 @@ public class WifiSettings extends RestrictedSettingsFragment boolean hasAvailableAccessPoints = false; int index = 0; - cacheRemoveAllPrefs(getPreferenceScreen()); + mAccessPointsPreferenceCategory.removePreference(mStatusMessagePreference); + cacheRemoveAllPrefs(mAccessPointsPreferenceCategory); for (AccessPoint accessPoint : accessPoints) { // Ignore access points that are out of range. if (accessPoint.getLevel() != -1) { @@ -665,12 +665,12 @@ public class WifiSettings extends RestrictedSettingsFragment onPreferenceTreeClick(preference); mOpenSsid = null; } - getPreferenceScreen().addPreference(preference); + mAccessPointsPreferenceCategory.addPreference(preference); accessPoint.setListener(this); preference.refresh(); } } - removeCachedPrefs(getPreferenceScreen()); + removeCachedPrefs(mAccessPointsPreferenceCategory); if (!hasAvailableAccessPoints) { setProgressBarVisible(true); Preference pref = new Preference(getContext()) { @@ -683,14 +683,16 @@ public class WifiSettings extends RestrictedSettingsFragment }; pref.setSelectable(false); pref.setSummary(R.string.wifi_empty_list_wifi_on); - pref.setOrder(0); + pref.setOrder(index++); pref.setKey(PREF_KEY_EMPTY_WIFI_LIST); - getPreferenceScreen().addPreference(pref); - mAddPreference.setOrder(1); - getPreferenceScreen().addPreference(mAddPreference); + mAccessPointsPreferenceCategory.addPreference(pref); + mAddPreference.setOrder(index++); + mAccessPointsPreferenceCategory.addPreference(mAddPreference); + setSavedNetworkPreferenceVisibility(); } else { mAddPreference.setOrder(index++); - getPreferenceScreen().addPreference(mAddPreference); + mAccessPointsPreferenceCategory.addPreference(mAddPreference); + setSavedNetworkPreferenceVisibility(); setProgressBarVisible(false); } if (mScanMenuItem != null) { @@ -699,7 +701,7 @@ public class WifiSettings extends RestrictedSettingsFragment break; case WifiManager.WIFI_STATE_ENABLING: - getPreferenceScreen().removeAll(); + mAccessPointsPreferenceCategory.removeAll(); setProgressBarVisible(true); break; @@ -710,6 +712,7 @@ public class WifiSettings extends RestrictedSettingsFragment case WifiManager.WIFI_STATE_DISABLED: setOffMessage(); + setSavedNetworkPreferenceVisibility(); setProgressBarVisible(false); if (mScanMenuItem != null) { mScanMenuItem.setEnabled(false); @@ -718,17 +721,20 @@ public class WifiSettings extends RestrictedSettingsFragment } } + private void setSavedNetworkPreferenceVisibility() { + if (mWifiTracker.doSavedNetworksExist()) { + mAdditionalSettingsPreferenceCategory.addPreference(mSavedNetworksPreference); + } else { + mAdditionalSettingsPreferenceCategory.removePreference(mSavedNetworksPreference); + } + } + private void setOffMessage() { if (isUiRestricted()) { if (!isUiRestrictedByOnlyAdmin()) { addMessagePreference(R.string.wifi_empty_list_user_restricted); } - getPreferenceScreen().removeAll(); - return; - } - - TextView emptyTextView = getEmptyTextView(); - if (emptyTextView == null) { + mAccessPointsPreferenceCategory.removeAll(); return; } @@ -744,35 +750,27 @@ public class WifiSettings extends RestrictedSettingsFragment if (!wifiScanningMode) { // Show only the brief text if the user is not allowed to configure scanning settings, // or the scanning mode has been turned off. - emptyTextView.setText(briefText, BufferType.SPANNABLE); + mStatusMessagePreference.setTitle(briefText); } else { - // Append the description of scanning settings with link. - final StringBuilder contentBuilder = new StringBuilder(); - contentBuilder.append(briefText); - contentBuilder.append("\n\n"); - contentBuilder.append(getText(R.string.wifi_scan_notify_text)); - LinkifyUtils.linkify(emptyTextView, contentBuilder, new LinkifyUtils.OnClickListener() { + LinkifyUtils.OnClickListener clickListener = new LinkifyUtils.OnClickListener() { @Override public void onClick() { - final SettingsActivity activity = - (SettingsActivity) WifiSettings.this.getActivity(); + final SettingsActivity activity = (SettingsActivity) getActivity(); activity.startPreferencePanel(ScanningSettings.class.getName(), null, R.string.location_scanning_screen_title, null, null, 0); } - }); + }; + mStatusMessagePreference.setText( + briefText, getText(R.string.wifi_scan_notify_text), clickListener); } - // Embolden and enlarge the brief description anyway. - Spannable boldSpan = (Spannable) emptyTextView.getText(); - boldSpan.setSpan( - new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0, - briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - getPreferenceScreen().removeAll(); + mAccessPointsPreferenceCategory.removeAll(); + mAccessPointsPreferenceCategory.addPreference(mStatusMessagePreference); } private void addMessagePreference(int messageId) { - TextView emptyTextView = getEmptyTextView(); - if (emptyTextView != null) emptyTextView.setText(messageId); - getPreferenceScreen().removeAll(); + mStatusMessagePreference.setTitle(messageId); + mAccessPointsPreferenceCategory.removeAll(); + mAccessPointsPreferenceCategory.addPreference(mStatusMessagePreference); } protected void setProgressBarVisible(boolean visible) { diff --git a/tests/robotests/src/com/android/settings/wifi/SavedNetworkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/wifi/SavedNetworkPreferenceControllerTest.java deleted file mode 100644 index 657c21e4fcc..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/SavedNetworkPreferenceControllerTest.java +++ /dev/null @@ -1,71 +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.wifi; - -import android.content.Context; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; - -import com.android.settings.SettingsRobolectricTestRunner; -import com.android.settings.TestConfig; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.annotation.Config; - -import java.util.List; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@RunWith(SettingsRobolectricTestRunner.class) -@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class SavedNetworkPreferenceControllerTest { - - @Mock - private Context mContext; - @Mock - private WifiManager mWifiManager; - - private SavedNetworkPreferenceController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mController = new SavedNetworkPreferenceController(mContext, mWifiManager); - } - - @Test - public void isAvailable_noSavedNetwork_shouldReturnFalse() { - when(mWifiManager.getConfiguredNetworks()).thenReturn(null); - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void isAvailable_hasSavedNetwork_shouldReturnTrue() { - List configs = mock(List.class); - when(configs.isEmpty()).thenReturn(false); - when(mWifiManager.getConfiguredNetworks()).thenReturn(configs); - - assertThat(mController.isAvailable()).isTrue(); - } -}