From 41f23de712eefc38ffe224ee227f3a0d116247a7 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Mon, 11 May 2020 21:30:42 +0800 Subject: [PATCH] [Wi-Fi] Replace WifiTracker with WifiPickerTracker in WifiSettings WifiSettings uses WifiTracker in SettingsLib while WifiSettings2 uses WifiPickerTracker in WifiSettingsLib. 1. Remove WifiSettings. 2. Rename WifiSettings2 to WifiSettings. 3. Remove the files only used in the removed WifiSettings. (Saved networks files are not included) Bug: 152571756 Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.wifi atest WifiSettingsUiTest Change-Id: I800b434c8049121db115cff87d51e164e4529999 --- AndroidManifest.xml | 19 - res/xml/wifi_settings.xml | 17 +- res/xml/wifi_settings2.xml | 48 - .../core/gateway/SettingsGateway.java | 3 - src/com/android/settings/panel/WifiPanel.java | 13 +- .../search/CustomSiteMapRegistry.java | 4 +- .../CreateShortcutPreferenceController.java | 12 - .../settings/wifi/AddNetworkFragment.java | 11 +- .../wifi/CaptivePortalNetworkCallback.java | 91 -- .../wifi/ConfigureAccessPointFragment.java | 178 --- .../wifi/ConnectedAccessPointPreference.java | 99 -- .../wifi/LongPressAccessPointPreference.java | 51 - .../android/settings/wifi/WifiSettings.java | 1243 +++++++---------- .../android/settings/wifi/WifiSettings2.java | 1131 --------------- .../search/CustomSiteMapRegistryTest.java | 6 +- .../ConfigureAccessPointFragmentTest.java | 100 -- .../ConnectedAccessPointPreferenceTest.java | 94 -- .../settings/wifi/WifiSettings2Test.java | 367 ----- .../settings/wifi/WifiSettingsTest.java | 326 ++--- .../settings/wifi/WifiSettingsUiTest.java | 189 +-- 20 files changed, 737 insertions(+), 3265 deletions(-) delete mode 100644 res/xml/wifi_settings2.xml delete mode 100644 src/com/android/settings/wifi/CaptivePortalNetworkCallback.java delete mode 100644 src/com/android/settings/wifi/ConfigureAccessPointFragment.java delete mode 100644 src/com/android/settings/wifi/ConnectedAccessPointPreference.java delete mode 100644 src/com/android/settings/wifi/LongPressAccessPointPreference.java delete mode 100644 src/com/android/settings/wifi/WifiSettings2.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java delete mode 100644 tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index a6ba436ac0c..55555a578a3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -269,25 +269,6 @@ android:value="true" /> - - - - - - - - - - - - - diff --git a/res/xml/wifi_settings.xml b/res/xml/wifi_settings.xml index a7f5a20774b..eadea683a6a 100644 --- a/res/xml/wifi_settings.xml +++ b/res/xml/wifi_settings.xml @@ -17,21 +17,19 @@ + android:title="@string/wifi_settings" + settings:keywords="@string/keywords_wifi"> + android:key="wifi_status_message"/> + android:layout="@layout/preference_category_no_label"/> + android:layout="@layout/preference_category_no_label"/> + android:fragment="com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2"/> + android:title="@string/wifi_data_usage"/> diff --git a/res/xml/wifi_settings2.xml b/res/xml/wifi_settings2.xml deleted file mode 100644 index 2bf39dbe28e..00000000000 --- a/res/xml/wifi_settings2.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index fea32cf8512..458c6f68a98 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -150,7 +150,6 @@ import com.android.settings.wifi.ConfigureWifiSettings; import com.android.settings.wifi.WifiAPITest; import com.android.settings.wifi.WifiInfo; import com.android.settings.wifi.WifiSettings; -import com.android.settings.wifi.WifiSettings2; import com.android.settings.wifi.calling.WifiCallingDisclaimerFragment; import com.android.settings.wifi.calling.WifiCallingSettings; import com.android.settings.wifi.p2p.WifiP2pSettings; @@ -168,7 +167,6 @@ public class SettingsGateway { AdvancedConnectedDeviceDashboardFragment.class.getName(), CreateShortcut.class.getName(), WifiSettings.class.getName(), - WifiSettings2.class.getName(), ConfigureWifiSettings.class.getName(), SavedAccessPointsWifiSettings.class.getName(), SavedAccessPointsWifiSettings2.class.getName(), @@ -323,7 +321,6 @@ public class SettingsGateway { SupportDashboardActivity.class.getName(), // Home page > Network & Internet Settings.WifiSettingsActivity.class.getName(), - Settings.WifiSettings2Activity.class.getName(), Settings.DataUsageSummaryActivity.class.getName(), // Home page > Connected devices Settings.BluetoothSettingsActivity.class.getName(), diff --git a/src/com/android/settings/panel/WifiPanel.java b/src/com/android/settings/panel/WifiPanel.java index 0efa804de03..3b36a57b397 100644 --- a/src/com/android/settings/panel/WifiPanel.java +++ b/src/com/android/settings/panel/WifiPanel.java @@ -20,14 +20,12 @@ import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.util.FeatureFlagUtils; import com.android.settings.R; import com.android.settings.SubSettings; import com.android.settings.slices.CustomSliceRegistry; import com.android.settings.slices.SliceBuilderUtils; import com.android.settings.wifi.WifiSettings; -import com.android.settings.wifi.WifiSettings2; import java.util.ArrayList; import java.util.List; @@ -63,20 +61,11 @@ public class WifiPanel implements PanelContent { public Intent getSeeMoreIntent() { final String screenTitle = mContext.getText(R.string.wifi_settings).toString(); - Intent intent; - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext, - WifiSettings2.class.getName(), - null /* key */, - screenTitle, - SettingsEnums.WIFI); - } else { - intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext, + final Intent intent = SliceBuilderUtils.buildSearchResultPageIntent(mContext, WifiSettings.class.getName(), null /* key */, screenTitle, SettingsEnums.WIFI); - } intent.setClassName(mContext.getPackageName(), SubSettings.class.getName()); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); return intent; diff --git a/src/com/android/settings/search/CustomSiteMapRegistry.java b/src/com/android/settings/search/CustomSiteMapRegistry.java index f1c62111404..cd716fafd2c 100644 --- a/src/com/android/settings/search/CustomSiteMapRegistry.java +++ b/src/com/android/settings/search/CustomSiteMapRegistry.java @@ -35,7 +35,7 @@ import com.android.settings.security.SecuritySettings; import com.android.settings.security.screenlock.ScreenLockSettings; import com.android.settings.system.SystemDashboardFragment; import com.android.settings.wallpaper.WallpaperSuggestionActivity; -import com.android.settings.wifi.WifiSettings2; +import com.android.settings.wifi.WifiSettings; import java.util.Map; @@ -55,7 +55,7 @@ public class CustomSiteMapRegistry { CUSTOM_SITE_MAP.put( WallpaperSuggestionActivity.class.getName(), DisplaySettings.class.getName()); CUSTOM_SITE_MAP.put( - WifiSettings2.class.getName(), NetworkDashboardFragment.class.getName()); + WifiSettings.class.getName(), NetworkDashboardFragment.class.getName()); CUSTOM_SITE_MAP.put(PowerUsageAdvanced.class.getName(), PowerUsageSummary.class.getName()); CUSTOM_SITE_MAP.put(RecentLocationRequestSeeAllFragment.class.getName(), LocationSettings.class.getName()); diff --git a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java index 4843736bf57..c0f7e1ffc37 100644 --- a/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java +++ b/src/com/android/settings/shortcut/CreateShortcutPreferenceController.java @@ -32,7 +32,6 @@ import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.graphics.drawable.LayerDrawable; import android.net.ConnectivityManager; -import android.util.FeatureFlagUtils; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -46,8 +45,6 @@ import androidx.preference.PreferenceGroup; import com.android.settings.R; import com.android.settings.Settings.TetherSettingsActivity; -import com.android.settings.Settings.WifiSettings2Activity; -import com.android.settings.Settings.WifiSettingsActivity; import com.android.settings.core.BasePreferenceController; import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; @@ -190,15 +187,6 @@ public class CreateShortcutPreferenceController extends BasePreferenceController Log.d(TAG, "Skipping non-system app: " + info.activityInfo); continue; } - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - if (info.activityInfo.name.endsWith(WifiSettingsActivity.class.getSimpleName())) { - continue; - } - } else { - if (info.activityInfo.name.endsWith(WifiSettings2Activity.class.getSimpleName())) { - continue; - } - } shortcuts.add(info); } Collections.sort(shortcuts, SHORTCUT_COMPARATOR); diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java index 2f0ecad16e7..7e17e380e79 100644 --- a/src/com/android/settings/wifi/AddNetworkFragment.java +++ b/src/com/android/settings/wifi/AddNetworkFragment.java @@ -34,7 +34,10 @@ import com.android.settings.R; import com.android.settings.core.InstrumentedFragment; import com.android.settings.wifi.dpp.WifiDppUtils; -public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase, +/** + * A full screen UI component for users to edit and add a Wi-Fi network. + */ +public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2, View.OnClickListener { final static String WIFI_CONFIG_KEY = "wifi_config_key"; @@ -46,7 +49,7 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; - private WifiConfigController mUIController; + private WifiConfigController2 mUIController; private Button mSubmitBtn; private Button mCancelBtn; @@ -76,7 +79,7 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf mSubmitBtn.setOnClickListener(this); mCancelBtn.setOnClickListener(this); ssidScannerButton.setOnClickListener(this); - mUIController = new WifiConfigController(this, rootView, null, getMode()); + mUIController = new WifiConfigController2(this, rootView, null, getMode()); return rootView; } @@ -124,7 +127,7 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf } @Override - public WifiConfigController getController() { + public WifiConfigController2 getController() { return mUIController; } diff --git a/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java b/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java deleted file mode 100644 index 630476f2b67..00000000000 --- a/src/com/android/settings/wifi/CaptivePortalNetworkCallback.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2018 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.net.ConnectivityManager.NetworkCallback; -import android.net.Network; -import android.net.NetworkCapabilities; - -import com.android.internal.util.Preconditions; - -/** Listens for changes to NetworkCapabilities to update the ConnectedAccessPointPreference. */ -class CaptivePortalNetworkCallback extends NetworkCallback { - - private final ConnectedAccessPointPreference mConnectedApPreference; - private final Network mNetwork; - - private boolean mIsCaptivePortal; - - CaptivePortalNetworkCallback( - Network network, ConnectedAccessPointPreference connectedApPreference) { - mNetwork = Preconditions.checkNotNull(network); - mConnectedApPreference = Preconditions.checkNotNull(connectedApPreference); - } - - @Override - public final void onLost(Network network) { - if (mNetwork.equals(network)) { - setIsCaptivePortal(false); - } - } - - @Override - public final void onCapabilitiesChanged(Network network, - NetworkCapabilities networkCapabilities) { - if (mNetwork.equals(network)) { - boolean isCaptivePortal = WifiUtils.canSignIntoNetwork(networkCapabilities); - setIsCaptivePortal(isCaptivePortal); - mConnectedApPreference.setCaptivePortal(isCaptivePortal); - } - } - - /** - * Called when captive portal capability changes for the current network. Default implementation - * is a no-op. Use {@link CaptivePortalNetworkCallback#isCaptivePortal()} to read new - * capability. - */ - public void onCaptivePortalCapabilityChanged() {} - - private void setIsCaptivePortal(boolean isCaptivePortal) { - if (isCaptivePortal == mIsCaptivePortal) { - return; - } - mIsCaptivePortal = isCaptivePortal; - onCaptivePortalCapabilityChanged(); - } - - /** - * Returns true if the supplied network and preference are not null and are the same as the - * originally supplied values. - */ - public final boolean isSameNetworkAndPreference( - Network network, ConnectedAccessPointPreference connectedApPreference) { - return mNetwork.equals(network) && mConnectedApPreference == connectedApPreference; - } - - /** - * Returns true if the most recent update to the NetworkCapabilities indicates a captive portal - * network and the Network was not lost in the interim. - */ - public final boolean isCaptivePortal() { - return mIsCaptivePortal; - } - - /** Returns the currently associated network. */ - public final Network getNetwork() { - return mNetwork; - } -} diff --git a/src/com/android/settings/wifi/ConfigureAccessPointFragment.java b/src/com/android/settings/wifi/ConfigureAccessPointFragment.java deleted file mode 100644 index 508d5491776..00000000000 --- a/src/com/android/settings/wifi/ConfigureAccessPointFragment.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2019 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.app.ActionBar; -import android.app.Activity; -import android.app.settings.SettingsEnums; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; - -import androidx.annotation.VisibleForTesting; - -import com.android.settings.R; -import com.android.settings.core.InstrumentedFragment; -import com.android.settingslib.wifi.AccessPoint; - -/** - * Detail page for configuring Wi-Fi network. - * - * The AccessPoint should be saved to the argument when launching this class in order to properly - * render this page. - * - * Migrating from Wi-Fi SettingsLib to to WifiTrackerLib, this object will be removed in the near - * future, please develop in {@link ConfigureWifiEntryFragment}. - */ -public class ConfigureAccessPointFragment extends InstrumentedFragment implements WifiConfigUiBase { - - public static final String NETWORK_CONFIG_KEY = "network_config_key"; - - private static final int SUBMIT_BUTTON_ID = android.R.id.button1; - private static final int CANCEL_BUTTON_ID = android.R.id.button2; - - private WifiConfigController mUiController; - private Button mSubmitBtn; - private Button mCancelBtn; - private AccessPoint mAccessPoint; - - @Override - public void onAttach(Context context) { - super.onAttach(context); - mAccessPoint = new AccessPoint(context, getArguments()); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.SETTINGS_WIFI_CONFIGURE_NETWORK; - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - final View rootView = inflater.inflate(R.layout.wifi_add_network_view, - container, false /* attachToRoot */); - - final Button neutral = rootView.findViewById(android.R.id.button3); - if (neutral != null) { - neutral.setVisibility(View.GONE); - } - - mSubmitBtn = rootView.findViewById(SUBMIT_BUTTON_ID); - mCancelBtn = rootView.findViewById(CANCEL_BUTTON_ID); - mSubmitBtn.setOnClickListener(view -> handleSubmitAction()); - mCancelBtn.setOnClickListener(view -> handleCancelAction()); - - mUiController = new WifiConfigController(this, rootView, mAccessPoint, - getMode(), false /* requestFocus */); - - /** - * For this add AccessPoint UI, need to remove the Home button, so set related feature as - * false. - */ - final ActionBar actionBar = getActivity().getActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setHomeButtonEnabled(false); - actionBar.setDisplayShowHomeEnabled(false); - } - - return rootView; - } - - @Override - public void onViewStateRestored(Bundle savedInstanceState) { - super.onViewStateRestored(savedInstanceState); - mUiController.updatePassword(); - } - - @Override - public int getMode() { - return WifiConfigUiBase.MODE_CONNECT; - } - - @Override - public WifiConfigController getController() { - return mUiController; - } - - @Override - public void dispatchSubmit() { - handleSubmitAction(); - } - - @Override - public void setTitle(int id) { - getActivity().setTitle(id); - } - - @Override - public void setTitle(CharSequence title) { - getActivity().setTitle(title); - } - - @Override - public void setSubmitButton(CharSequence text) { - mSubmitBtn.setText(text); - } - - @Override - public void setCancelButton(CharSequence text) { - mCancelBtn.setText(text); - } - - @Override - public void setForgetButton(CharSequence text) { - // AddNetwork doesn't need forget button. - } - - @Override - public Button getSubmitButton() { - return mSubmitBtn; - } - - @Override - public Button getCancelButton() { - return mCancelBtn; - } - - @Override - public Button getForgetButton() { - // AddNetwork doesn't need forget button. - return null; - } - - @VisibleForTesting - void handleSubmitAction() { - final Intent intent = new Intent(); - final Activity activity = getActivity(); - intent.putExtra(NETWORK_CONFIG_KEY, mUiController.getConfig()); - activity.setResult(Activity.RESULT_OK, intent); - activity.finish(); - } - - @VisibleForTesting - void handleCancelAction() { - final Activity activity = getActivity(); - activity.setResult(Activity.RESULT_CANCELED); - activity.finish(); - } -} diff --git a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java b/src/com/android/settings/wifi/ConnectedAccessPointPreference.java deleted file mode 100644 index e9046025bbe..00000000000 --- a/src/com/android/settings/wifi/ConnectedAccessPointPreference.java +++ /dev/null @@ -1,99 +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.view.View; - -import androidx.annotation.DrawableRes; -import androidx.fragment.app.Fragment; -import androidx.preference.PreferenceViewHolder; - -import com.android.settings.R; -import com.android.settingslib.wifi.AccessPoint; - -/** - * An AP preference for the currently connected AP. - * - * Migrating from Wi-Fi SettingsLib to to WifiTrackerLib, this object will be removed in the near - * future, please develop in {@link ConnectedWifiEntryPreference}. - */ -public class ConnectedAccessPointPreference extends LongPressAccessPointPreference implements - View.OnClickListener { - - private OnGearClickListener mOnGearClickListener; - private boolean mIsCaptivePortal; - - public ConnectedAccessPointPreference(AccessPoint accessPoint, Context context, - UserBadgeCache cache, @DrawableRes int iconResId, boolean forSavedNetworks, - Fragment fragment) { - super(accessPoint, context, cache, forSavedNetworks, iconResId, fragment); - } - - @Override - protected int getWidgetLayoutResourceId() { - return R.layout.preference_widget_gear_optional_background; - } - - @Override - public void refresh() { - super.refresh(); - - setShowDivider(mIsCaptivePortal); - if (mIsCaptivePortal) { - setSummary(R.string.wifi_tap_to_sign_in); - } - } - - public void setOnGearClickListener(OnGearClickListener l) { - mOnGearClickListener = l; - notifyChanged(); - } - - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - - final View gear = holder.findViewById(R.id.settings_button); - gear.setOnClickListener(this); - - final View gearNoBg = holder.findViewById(R.id.settings_button_no_background); - gearNoBg.setVisibility(mIsCaptivePortal ? View.INVISIBLE : View.VISIBLE); - gear.setVisibility(mIsCaptivePortal ? View.VISIBLE : View.INVISIBLE); - } - - @Override - public void onClick(View v) { - if (v.getId() == R.id.settings_button) { - if (mOnGearClickListener != null) { - mOnGearClickListener.onGearClick(this); - } - } - } - - public void setCaptivePortal(boolean isCaptivePortal) { - if (mIsCaptivePortal != isCaptivePortal) { - mIsCaptivePortal = isCaptivePortal; - refresh(); - } - } - - public interface OnGearClickListener { - void onGearClick(ConnectedAccessPointPreference p); - } - -} diff --git a/src/com/android/settings/wifi/LongPressAccessPointPreference.java b/src/com/android/settings/wifi/LongPressAccessPointPreference.java deleted file mode 100644 index 15903250fd1..00000000000 --- a/src/com/android/settings/wifi/LongPressAccessPointPreference.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2015 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 androidx.fragment.app.Fragment; -import androidx.preference.PreferenceViewHolder; - -import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.AccessPointPreference; - -/** - * An AP preference for the currently connected AP. - * - * Migrating from Wi-Fi SettingsLib to to WifiTrackerLib, this object will be removed in the near - * future, please develop in {@link com.android.settingslib.wifi.LongPressWifiEntryPreference}. - */ -public class LongPressAccessPointPreference extends AccessPointPreference { - - private final Fragment mFragment; - - public LongPressAccessPointPreference(AccessPoint accessPoint, Context context, - UserBadgeCache cache, boolean forSavedNetworks, int iconResId, Fragment fragment) { - super(accessPoint, context, cache, iconResId, forSavedNetworks); - mFragment = fragment; - } - - @Override - public void onBindViewHolder(final PreferenceViewHolder view) { - super.onBindViewHolder(view); - if (mFragment != null) { - view.itemView.setOnCreateContextMenuListener(mFragment); - view.itemView.setTag(this); - view.itemView.setLongClickable(true); - } - } -} diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java index 1ba99a29f26..f432c60e721 100644 --- a/src/com/android/settings/wifi/WifiSettings.java +++ b/src/com/android/settings/wifi/WifiSettings.java @@ -16,31 +16,32 @@ package com.android.settings.wifi; -import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED; import static android.os.UserManager.DISALLOW_CONFIG_WIFI; -import android.annotation.NonNull; import android.app.Activity; import android.app.Dialog; import android.app.settings.SettingsEnums; +import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkInfo; -import android.net.NetworkInfo.State; -import android.net.NetworkRequest; +import android.net.NetworkScoreManager; import android.net.NetworkTemplate; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.PowerManager; +import android.os.Process; +import android.os.SimpleClock; +import android.os.SystemClock; import android.provider.Settings; +import android.text.TextUtils; import android.util.FeatureFlagUtils; import android.util.Log; import android.view.ContextMenu; @@ -50,7 +51,6 @@ import android.view.MenuItem; import android.view.View; import android.widget.Toast; -import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; @@ -68,56 +68,54 @@ import com.android.settings.datausage.DataUsageUtils; import com.android.settings.location.ScanningSettings; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.widget.SwitchBarController; -import com.android.settings.wifi.details.WifiNetworkDetailsFragment; +import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2; import com.android.settings.wifi.dpp.WifiDppUtils; +import com.android.settingslib.HelpUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.search.Indexable; import com.android.settingslib.search.SearchIndexable; -import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.AccessPoint.AccessPointListener; -import com.android.settingslib.wifi.AccessPointPreference; +import com.android.settingslib.wifi.LongPressWifiEntryPreference; import com.android.settingslib.wifi.WifiSavedConfigUtils; -import com.android.settingslib.wifi.WifiTracker; -import com.android.settingslib.wifi.WifiTrackerFactory; +import com.android.wifitrackerlib.WifiEntry; +import com.android.wifitrackerlib.WifiEntry.ConnectCallback; +import com.android.wifitrackerlib.WifiPickerTracker; +import java.time.Clock; +import java.time.ZoneOffset; import java.util.List; +import java.util.Optional; /** - * Two types of UI are provided here. - * - * The first is for "usual Settings", appearing as any other Setup fragment. - * - * The second is for Setup Wizard, with a simplified interface that hides the action bar - * and menus. - * - * Migrating from Wi-Fi SettingsLib to to WifiTrackerLib, this object will be removed in the near - * future, please develop in {@link WifiSettings2}. + * UI for Wi-Fi settings screen */ @SearchIndexable public class WifiSettings extends RestrictedSettingsFragment - implements Indexable, WifiTracker.WifiListener, AccessPointListener, - WifiDialog.WifiDialogListener, DialogInterface.OnDismissListener { + implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback, + WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener { private static final String TAG = "WifiSettings"; - private static final int MENU_ID_CONNECT = Menu.FIRST + 6; + // IDs of context menu + static final int MENU_ID_CONNECT = Menu.FIRST + 1; @VisibleForTesting - static final int MENU_ID_FORGET = Menu.FIRST + 7; - private static final int MENU_ID_MODIFY = Menu.FIRST + 8; + static final int MENU_ID_DISCONNECT = Menu.FIRST + 2; + @VisibleForTesting + static final int MENU_ID_FORGET = Menu.FIRST + 3; + static final int MENU_ID_MODIFY = Menu.FIRST + 4; - public static final int WIFI_DIALOG_ID = 1; + // Max age of tracked WifiEntries + private static final long MAX_SCAN_AGE_MILLIS = 15_000; + // Interval between initiating WifiPickerTracker scans + private static final long SCAN_INTERVAL_MILLIS = 10_000; @VisibleForTesting static final int ADD_NETWORK_REQUEST = 2; - static final int CONFIG_NETWORK_REQUEST = 3; - - // Instance state keys - private static final String SAVE_DIALOG_MODE = "dialog_mode"; - private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state"; + static final int MANAGE_SUBSCRIPTION = 4; private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list"; + // TODO(b/70983952): Rename these to use WifiEntry instead of AccessPoint. private static final String PREF_KEY_CONNECTED_ACCESS_POINTS = "connected_access_point"; private static final String PREF_KEY_ACCESS_POINTS = "access_points"; private static final String PREF_KEY_CONFIGURE_WIFI_SETTINGS = "configure_wifi_settings"; @@ -128,27 +126,48 @@ public class WifiSettings extends RestrictedSettingsFragment private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; + public static final int WIFI_DIALOG_ID = 1; + + // Instance state keys + private static final String SAVE_DIALOG_MODE = "dialog_mode"; + private static final String SAVE_DIALOG_WIFIENTRY_KEY = "wifi_ap_key"; + + // Cache at onCreateContextMenu and use at onContextItemSelected. Don't use it in other methods. + private WifiEntry mSelectedWifiEntry; + + // Save the dialog details + private int mDialogMode; + private String mDialogWifiEntryKey; + private WifiEntry mDialogWifiEntry; + + // This boolean extra specifies whether to enable the Next button when connected. Used by + // account creation outside of setup wizard. + private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect"; + + // Enable the Next button when a Wi-Fi network is connected. + private boolean mEnableNextOnConnection; + + // This string extra specifies a network to open the connect dialog on, so the user can enter + // network credentials. This is used by quick settings for secured networks, among other + // things. + private static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid"; + private String mOpenSsid; + private static boolean isVerboseLoggingEnabled() { - return WifiTracker.sVerboseLogging || Log.isLoggable(TAG, Log.VERBOSE); + return WifiPickerTracker.isVerboseLoggingEnabled(); } - private final Runnable mUpdateAccessPointsRunnable = () -> { - updateAccessPointPreferences(); + private final Runnable mUpdateWifiEntryPreferencesRunnable = () -> { + updateWifiEntryPreferences(); }; private final Runnable mHideProgressBarRunnable = () -> { setProgressBarVisible(false); }; - @VisibleForTesting - WifiManager mWifiManager; - @VisibleForTesting - ConnectivityManager mConnectivityManager; + protected WifiManager mWifiManager; private WifiManager.ActionListener mConnectListener; private WifiManager.ActionListener mSaveListener; private WifiManager.ActionListener mForgetListener; - @VisibleForTesting - CaptivePortalNetworkCallback mCaptivePortalNetworkCallback; - private Network mLastNetworkCaptivePortalAppStarted; /** * The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is neccesary to @@ -158,37 +177,19 @@ public class WifiSettings extends RestrictedSettingsFragment private boolean mIsRestricted; private WifiEnabler mWifiEnabler; - // An access point being edited is stored here. - private AccessPoint mSelectedAccessPoint; - private WifiDialog mDialog; + // Worker thread used for WifiPickerTracker work + private HandlerThread mWorkerThread; + + @VisibleForTesting + WifiPickerTracker mWifiPickerTracker; + + private WifiDialog2 mDialog; private View mProgressHeader; - // this boolean extra specifies whether to disable the Next button when not connected. Used by - // account creation outside of setup wizard. - private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect"; - // This string extra specifies a network to open the connect dialog on, so the user can enter - // network credentials. This is used by quick settings for secured networks, among other - // things. - public static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid"; - - // should Next button only be enabled when we have a connection? - private boolean mEnableNextOnConnection; - - // Save the dialog details - private int mDialogMode; - private AccessPoint mDlgAccessPoint; - private Bundle mAccessPointSavedState; - - @VisibleForTesting - WifiTracker mWifiTracker; - private String mOpenSsid; - - private AccessPointPreference.UserBadgeCache mUserBadgeCache; - - private PreferenceCategory mConnectedAccessPointPreferenceCategory; - private PreferenceCategory mAccessPointsPreferenceCategory; + private PreferenceCategory mConnectedWifiEntryPreferenceCategory; + private PreferenceCategory mWifiEntryPreferenceCategory; @VisibleForTesting AddWifiNetworkPreference mAddWifiNetworkPreference; @VisibleForTesting @@ -204,17 +205,6 @@ public class WifiSettings extends RestrictedSettingsFragment * network once connected. */ private boolean mClickedConnect; - @ConnectSource int mConnectSource = CONNECT_SOURCE_UNSPECIFIED; - - private static final int CONNECT_SOURCE_UNSPECIFIED = 0; - private static final int CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK = 1; - private static final int CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK = 2; - - @IntDef({CONNECT_SOURCE_UNSPECIFIED, CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK, - CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK}) - private @interface ConnectSource {} - - /* End of "used in Wifi Setup context" */ public WifiSettings() { super(DISALLOW_CONFIG_WIFI); @@ -238,17 +228,6 @@ public class WifiSettings extends RestrictedSettingsFragment public void onCreate(Bundle icicle) { super.onCreate(icicle); - if (FeatureFlagUtils.isEnabled(getContext(), FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - final Intent intent = new Intent("android.settings.WIFI_SETTINGS2"); - final Bundle extras = getActivity().getIntent().getExtras(); - if (extras != null) { - intent.putExtras(extras); - } - getContext().startActivity(intent); - finish(); - return; - } - // TODO(b/37429702): Add animations and preference comparator back after initial screen is // loaded (ODR). setAnimationAllowed(false); @@ -261,15 +240,12 @@ public class WifiSettings extends RestrictedSettingsFragment private void addPreferences() { addPreferencesFromResource(R.xml.wifi_settings); - mConnectedAccessPointPreferenceCategory = - (PreferenceCategory) findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS); - mAccessPointsPreferenceCategory = - (PreferenceCategory) findPreference(PREF_KEY_ACCESS_POINTS); + mConnectedWifiEntryPreferenceCategory = findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS); + mWifiEntryPreferenceCategory = findPreference(PREF_KEY_ACCESS_POINTS); mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS); mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS); mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext()); - mStatusMessagePreference = (LinkablePreference) findPreference(PREF_KEY_STATUS_MESSAGE); - mUserBadgeCache = new AccessPointPreference.UserBadgeCache(getPackageManager()); + mStatusMessagePreference = findPreference(PREF_KEY_STATUS_MESSAGE); mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE); mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext())); mDataUsagePreference.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), @@ -281,13 +257,32 @@ public class WifiSettings extends RestrictedSettingsFragment public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mWifiTracker = WifiTrackerFactory.create( - getActivity(), this, getSettingsLifecycle(), true, true); - mWifiManager = mWifiTracker.getManager(); + final Context context = getContext(); + mWorkerThread = new HandlerThread(TAG + + "{" + Integer.toHexString(System.identityHashCode(this)) + "}", + Process.THREAD_PRIORITY_BACKGROUND); + mWorkerThread.start(); + final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) { + @Override + public long millis() { + return SystemClock.elapsedRealtime(); + } + }; + mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context, + context.getSystemService(WifiManager.class), + context.getSystemService(ConnectivityManager.class), + context.getSystemService(NetworkScoreManager.class), + new Handler(Looper.getMainLooper()), + mWorkerThread.getThreadHandler(), + elapsedRealtimeClock, + MAX_SCAN_AGE_MILLIS, + SCAN_INTERVAL_MILLIS, + this); final Activity activity = getActivity(); + if (activity != null) { - mConnectivityManager = getActivity().getSystemService(ConnectivityManager.class); + mWifiManager = getActivity().getSystemService(WifiManager.class); } mConnectListener = new WifiConnectListener(getActivity()); @@ -323,35 +318,19 @@ public class WifiSettings extends RestrictedSettingsFragment } } }; + registerForContextMenu(getListView()); + setHasOptionsMenu(true); if (savedInstanceState != null) { mDialogMode = savedInstanceState.getInt(SAVE_DIALOG_MODE); - if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) { - mAccessPointSavedState = - savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE); - } + mDialogWifiEntryKey = savedInstanceState.getString(SAVE_DIALOG_WIFIENTRY_KEY); } - // if we're supposed to enable/disable the Next button based on our current connection - // state, start it off in the right state - Intent intent = getActivity().getIntent(); + // If we're supposed to enable/disable the Next button based on our current connection + // state, start it off in the right state. + final Intent intent = getActivity().getIntent(); mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false); - if (mEnableNextOnConnection) { - if (hasNextButton()) { - final ConnectivityManager connectivity = (ConnectivityManager) - getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); - if (connectivity != null) { - NetworkInfo info = connectivity.getNetworkInfo( - ConnectivityManager.TYPE_WIFI); - changeNextButtonState(info.isConnected()); - } - } - } - - registerForContextMenu(getListView()); - setHasOptionsMenu(true); - if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) { mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID); } @@ -359,26 +338,23 @@ public class WifiSettings extends RestrictedSettingsFragment @Override public void onDestroyView() { - super.onDestroyView(); - if (mWifiEnabler != null) { mWifiEnabler.teardownSwitchController(); } + mWorkerThread.quit(); + + super.onDestroyView(); } @Override public void onStart() { super.onStart(); - // On/off switch is hidden for Setup Wizard (returns null) mWifiEnabler = createWifiEnabler(); if (mIsRestricted) { restrictUi(); - return; } - - onWifiStateChanged(mWifiManager.getWifiState()); } private void restrictUi() { @@ -389,7 +365,7 @@ public class WifiSettings extends RestrictedSettingsFragment } /** - * @return new WifiEnabler or null (as overridden by WifiSettingsForSetupWizard) + * @return new WifiEnabler */ private WifiEnabler createWifiEnabler() { final SettingsActivity activity = (SettingsActivity) getActivity(); @@ -413,6 +389,8 @@ public class WifiSettings extends RestrictedSettingsFragment if (mWifiEnabler != null) { mWifiEnabler.resume(activity); } + + changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null); } @Override @@ -425,9 +403,8 @@ public class WifiSettings extends RestrictedSettingsFragment @Override public void onStop() { - getView().removeCallbacks(mUpdateAccessPointsRunnable); + getView().removeCallbacks(mUpdateWifiEntryPreferencesRunnable); getView().removeCallbacks(mHideProgressBarRunnable); - unregisterCaptivePortalNetworkCallback(); super.onStop(); } @@ -443,14 +420,21 @@ public class WifiSettings extends RestrictedSettingsFragment if (mDialog != null) { mDialog.dismiss(); } - mWifiTracker.resumeScanning(); } return; } else if (requestCode == CONFIG_NETWORK_REQUEST) { if (resultCode == Activity.RESULT_OK) { - handleConfigNetworkSubmitEvent(data); + final WifiConfiguration wifiConfiguration = data.getParcelableExtra( + ConfigureWifiEntryFragment.NETWORK_CONFIG_KEY); + if (wifiConfiguration != null) { + mWifiManager.connect(wifiConfiguration, + new WifiConnectActionListener()); + } } return; + } else if (requestCode == MANAGE_SUBSCRIPTION) { + //Do nothing + return; } final boolean formerlyRestricted = mIsRestricted; @@ -480,78 +464,72 @@ public class WifiSettings extends RestrictedSettingsFragment // If dialog has been shown, save its state. if (mDialog != null) { outState.putInt(SAVE_DIALOG_MODE, mDialogMode); - if (mDlgAccessPoint != null) { - mAccessPointSavedState = new Bundle(); - mDlgAccessPoint.saveWifiState(mAccessPointSavedState); - outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState); - } + outState.putString(SAVE_DIALOG_WIFIENTRY_KEY, mDialogWifiEntryKey); } } @Override public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) { Preference preference = (Preference) view.getTag(); - - if (preference instanceof LongPressAccessPointPreference) { - mSelectedAccessPoint = - ((LongPressAccessPointPreference) preference).getAccessPoint(); - menu.setHeaderTitle(mSelectedAccessPoint.getTitle()); - if (mSelectedAccessPoint.isConnectable()) { - menu.add(Menu.NONE, MENU_ID_CONNECT, 0 /* order */, R.string.wifi_connect); - } - - WifiConfiguration config = mSelectedAccessPoint.getConfig(); - // Some configs are ineditable - if (WifiUtils.isNetworkLockedDown(getActivity(), config)) { - return; - } - - // "forget" for normal saved network. And "disconnect" for ephemeral network because it - // could only be disconnected and be put in blacklists so it won't be used again. - if (mSelectedAccessPoint.isSaved() || mSelectedAccessPoint.isEphemeral()) { - final int stringId = mSelectedAccessPoint.isEphemeral() ? - R.string.wifi_disconnect_button_text : R.string.forget; - menu.add(Menu.NONE, MENU_ID_FORGET, 0 /* order */, stringId); - } - - if (mSelectedAccessPoint.isSaved() && !mSelectedAccessPoint.isActive()) { - menu.add(Menu.NONE, MENU_ID_MODIFY, 0 /* order */, R.string.wifi_modify); - } + if (!(preference instanceof LongPressWifiEntryPreference)) { + // Do nothing. + return; } + + // Cache the WifiEntry for onContextItemSelected. Don't use it in other methods. + mSelectedWifiEntry = ((LongPressWifiEntryPreference) preference).getWifiEntry(); + + menu.setHeaderTitle(mSelectedWifiEntry.getTitle()); + if (mSelectedWifiEntry.canConnect()) { + menu.add(Menu.NONE, MENU_ID_CONNECT, 0 /* order */, R.string.wifi_connect); + } + + if (mSelectedWifiEntry.canDisconnect()) { + menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */, + R.string.wifi_disconnect_button_text); + } + + // "forget" for normal saved network. And "disconnect" for ephemeral network because it + // could only be disconnected and be put in blacklists so it won't be used again. + if (canForgetNetwork()) { + menu.add(Menu.NONE, MENU_ID_FORGET, 0 /* order */, R.string.forget); + } + + WifiConfiguration config = mSelectedWifiEntry.getWifiConfiguration(); + // Some configs are ineditable + if (WifiUtils.isNetworkLockedDown(getActivity(), config)) { + return; + } + + if (mSelectedWifiEntry.isSaved() && mSelectedWifiEntry.getConnectedState() + != WifiEntry.CONNECTED_STATE_CONNECTED) { + menu.add(Menu.NONE, MENU_ID_MODIFY, 0 /* order */, R.string.wifi_modify); + } + } + + private boolean canForgetNetwork() { + return mSelectedWifiEntry.canForget() && !WifiUtils.isNetworkLockedDown(getActivity(), + mSelectedWifiEntry.getWifiConfiguration()); } @Override public boolean onContextItemSelected(MenuItem item) { - if (mSelectedAccessPoint == null) { - return super.onContextItemSelected(item); - } switch (item.getItemId()) { - case MENU_ID_CONNECT: { - boolean isSavedNetwork = mSelectedAccessPoint.isSaved(); - if (isSavedNetwork) { - connect(mSelectedAccessPoint.getConfig(), isSavedNetwork, - CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK); - } else if ((mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_NONE) || - (mSelectedAccessPoint.getSecurity() == AccessPoint.SECURITY_OWE)) { - /** Bypass dialog for unsecured networks */ - mSelectedAccessPoint.generateOpenNetworkConfig(); - connect(mSelectedAccessPoint.getConfig(), isSavedNetwork, - CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK); - } else { - showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_CONNECT); - } + case MENU_ID_CONNECT: + connect(mSelectedWifiEntry, true /* editIfNoConfig */, false /* fullScreenEdit */); return true; - } - case MENU_ID_FORGET: { - forget(); + case MENU_ID_DISCONNECT: + mSelectedWifiEntry.disconnect(null /* callback */); return true; - } - case MENU_ID_MODIFY: { - showDialog(mSelectedAccessPoint, WifiConfigUiBase.MODE_MODIFY); + case MENU_ID_FORGET: + forget(mSelectedWifiEntry); return true; - } + case MENU_ID_MODIFY: + showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); + return true; + default: + return super.onContextItemSelected(item); } - return super.onContextItemSelected(item); } @Override @@ -562,44 +540,16 @@ public class WifiSettings extends RestrictedSettingsFragment return super.onPreferenceTreeClick(preference); } - if (preference instanceof LongPressAccessPointPreference) { - mSelectedAccessPoint = ((LongPressAccessPointPreference) preference).getAccessPoint(); - if (mSelectedAccessPoint == null) { - return false; - } - if (mSelectedAccessPoint.isActive()) { - return super.onPreferenceTreeClick(preference); - } - /** - * Bypass dialog and connect to unsecured networks, or previously connected saved - * networks, or Passpoint provided networks. - */ - switch (WifiUtils.getConnectingType(mSelectedAccessPoint)) { - case WifiUtils.CONNECT_TYPE_OSU_PROVISION: - mSelectedAccessPoint.startOsuProvisioning(mConnectListener); - mClickedConnect = true; - break; + if (preference instanceof LongPressWifiEntryPreference) { + final WifiEntry selectedEntry = + ((LongPressWifiEntryPreference) preference).getWifiEntry(); - case WifiUtils.CONNECT_TYPE_OPEN_NETWORK: - mSelectedAccessPoint.generateOpenNetworkConfig(); - connect(mSelectedAccessPoint.getConfig(), - mSelectedAccessPoint.isSaved(), - CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK); - break; - - case WifiUtils.CONNECT_TYPE_SAVED_NETWORK: - connect(mSelectedAccessPoint.getConfig(), - true /* isSavedNetwork */, - CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK); - break; - - default: - final Bundle bundle = ((LongPressAccessPointPreference) preference).getExtras(); - mSelectedAccessPoint.saveWifiState(bundle); - launchConfigNewNetworkFragment(mSelectedAccessPoint, - WifiConfigUiBase.MODE_CONNECT, bundle); - break; + if (selectedEntry.shouldEditBeforeConnect()) { + launchConfigNewNetworkFragment(selectedEntry); + return true; } + + connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */); } else if (preference == mAddWifiNetworkPreference) { onAddNetworkPressed(); } else { @@ -608,14 +558,12 @@ public class WifiSettings extends RestrictedSettingsFragment return true; } - private void showDialog(AccessPoint accessPoint, int dialogMode) { - if (accessPoint != null) { - WifiConfiguration config = accessPoint.getConfig(); - if (WifiUtils.isNetworkLockedDown(getActivity(), config) && accessPoint.isActive()) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), - RestrictedLockUtilsInternal.getDeviceOwner(getActivity())); - return; - } + private void showDialog(WifiEntry wifiEntry, int dialogMode) { + if (WifiUtils.isNetworkLockedDown(getActivity(), wifiEntry.getWifiConfiguration()) + && wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) { + RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), + RestrictedLockUtilsInternal.getDeviceOwner(getActivity())); + return; } if (mDialog != null) { @@ -624,7 +572,8 @@ public class WifiSettings extends RestrictedSettingsFragment } // Save the access point and edit mode - mDlgAccessPoint = accessPoint; + mDialogWifiEntry = wifiEntry; + mDialogWifiEntryKey = wifiEntry.getKey(); mDialogMode = dialogMode; showDialog(WIFI_DIALOG_ID); @@ -635,18 +584,12 @@ public class WifiSettings extends RestrictedSettingsFragment switch (dialogId) { case WIFI_DIALOG_ID: // modify network - if (mDlgAccessPoint == null && mAccessPointSavedState != null) { - // restore AP from save state - mDlgAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState); - // Reset the saved access point data - mAccessPointSavedState = null; - } - mDialog = WifiDialog - .createModal(getActivity(), this, mDlgAccessPoint, mDialogMode); - mSelectedAccessPoint = mDlgAccessPoint; + mDialog = WifiDialog2 + .createModal(getActivity(), this, mDialogWifiEntry, mDialogMode); return mDialog; + default: + return super.onCreateDialog(dialogId); } - return super.onCreateDialog(dialogId); } @Override @@ -659,6 +602,8 @@ public class WifiSettings extends RestrictedSettingsFragment public void onDismiss(DialogInterface dialog) { // We don't keep any dialog object when dialog was dismissed. mDialog = null; + mDialogWifiEntry = null; + mDialogWifiEntryKey = null; } @Override @@ -671,56 +616,33 @@ public class WifiSettings extends RestrictedSettingsFragment } } - /** - * Called to indicate the list of AccessPoints has been updated and - * getAccessPoints should be called to get the latest information. - */ - @Override - public void onAccessPointsChanged() { - Log.d(TAG, "onAccessPointsChanged (WifiTracker) callback initiated"); - updateAccessPointsDelayed(); - } - - /** - * Updates access points from {@link WifiManager#getScanResults()}. Adds a delay to have - * progress bar displayed before starting to modify APs. - */ - private void updateAccessPointsDelayed() { - // Safeguard from some delayed event handling - if (getActivity() != null && !mIsRestricted && mWifiManager.isWifiEnabled()) { - final View view = getView(); - final Handler handler = view.getHandler(); - if (handler != null && handler.hasCallbacks(mUpdateAccessPointsRunnable)) { - return; - } - setProgressBarVisible(true); - view.postDelayed(mUpdateAccessPointsRunnable, 300 /* delay milliseconds */); - } - } - /** Called when the state of Wifi has changed. */ @Override - public void onWifiStateChanged(int state) { + public void onWifiStateChanged() { if (mIsRestricted) { return; } + final int wifiState = mWifiPickerTracker.getWifiState(); + + if (isVerboseLoggingEnabled()) { + Log.i(TAG, "onWifiStateChanged called with wifi state: " + wifiState); + } - final int wifiState = mWifiManager.getWifiState(); switch (wifiState) { case WifiManager.WIFI_STATE_ENABLED: - updateAccessPointPreferences(); + updateWifiEntryPreferences(); break; case WifiManager.WIFI_STATE_ENABLING: - removeConnectedAccessPointPreference(); - removeAccessPointPreference(); + removeConnectedWifiEntryPreference(); + removeWifiEntryPreference(); addMessagePreference(R.string.wifi_starting); setProgressBarVisible(true); break; case WifiManager.WIFI_STATE_DISABLING: - removeConnectedAccessPointPreference(); - removeAccessPointPreference(); + removeConnectedWifiEntryPreference(); + removeWifiEntryPreference(); addMessagePreference(R.string.wifi_stopping); break; @@ -728,241 +650,177 @@ public class WifiSettings extends RestrictedSettingsFragment setOffMessage(); setAdditionalSettingsSummaries(); setProgressBarVisible(false); - mConnectSource = CONNECT_SOURCE_UNSPECIFIED; mClickedConnect = false; break; } } - /** - * Called when the connection state of wifi has changed. - */ @Override - public void onConnectedChanged() { - changeNextButtonState(mWifiTracker.isConnected()); - } + public void onWifiEntriesChanged() { + updateWifiEntryPreferencesDelayed(); + changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null); - /** Helper method to return whether an AccessPoint is disabled due to a wrong password */ - private static boolean isDisabledByWrongPassword(AccessPoint accessPoint) { - WifiConfiguration config = accessPoint.getConfig(); - if (config == null) { - return false; - } - WifiConfiguration.NetworkSelectionStatus networkStatus = - config.getNetworkSelectionStatus(); - if (networkStatus == null - || networkStatus.getNetworkSelectionStatus() == NETWORK_SELECTION_ENABLED) { - return false; - } - int reason = networkStatus.getNetworkSelectionDisableReason(); - return WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD == reason; - } - - private void updateAccessPointPreferences() { - // in case state has changed - if (!mWifiManager.isWifiEnabled()) { - return; - } - // AccessPoints are sorted by the WifiTracker - final List accessPoints = mWifiTracker.getAccessPoints(); - if (isVerboseLoggingEnabled()) { - Log.i(TAG, "updateAccessPoints called for: " + accessPoints); - } - - boolean hasAvailableAccessPoints = false; - mStatusMessagePreference.setVisible(false); - mConnectedAccessPointPreferenceCategory.setVisible(true); - mAccessPointsPreferenceCategory.setVisible(true); - - cacheRemoveAllPrefs(mAccessPointsPreferenceCategory); - - int index = - configureConnectedAccessPointPreferenceCategory(accessPoints) ? 1 : 0; - int numAccessPoints = accessPoints.size(); - for (; index < numAccessPoints; index++) { - AccessPoint accessPoint = accessPoints.get(index); - // Ignore access points that are out of range. - if (accessPoint.isReachable()) { - String key = accessPoint.getKey(); - hasAvailableAccessPoints = true; - LongPressAccessPointPreference pref = - (LongPressAccessPointPreference) getCachedPreference(key); - if (pref != null) { - pref.setOrder(index); - continue; - } - LongPressAccessPointPreference preference = - createLongPressAccessPointPreference(accessPoint); - preference.setKey(key); - preference.setOrder(index); - if (mOpenSsid != null && mOpenSsid.equals(accessPoint.getSsidStr()) - && (accessPoint.getSecurity() != AccessPoint.SECURITY_NONE && - accessPoint.getSecurity() != AccessPoint.SECURITY_OWE)) { - if (!accessPoint.isSaved() || isDisabledByWrongPassword(accessPoint)) { - onPreferenceTreeClick(preference); - mOpenSsid = null; - } - } - mAccessPointsPreferenceCategory.addPreference(preference); - accessPoint.setListener(WifiSettings.this); - preference.refresh(); + // Edit the Wi-Fi network of specified SSID. + if (mOpenSsid != null) { + Optional matchedWifiEntry = mWifiPickerTracker.getWifiEntries().stream() + .filter(wifiEntry -> TextUtils.equals(mOpenSsid, wifiEntry.getSsid())) + .filter(wifiEntry -> wifiEntry.getSecurity() != WifiEntry.SECURITY_NONE + && wifiEntry.getSecurity() != WifiEntry.SECURITY_OWE) + .filter(wifiEntry -> !wifiEntry.isSaved() + || isDisabledByWrongPassword(wifiEntry)) + .findFirst(); + if (matchedWifiEntry.isPresent()) { + mOpenSsid = null; + launchConfigNewNetworkFragment(matchedWifiEntry.get()); } } - removeCachedPrefs(mAccessPointsPreferenceCategory); - mAddWifiNetworkPreference.setOrder(index); - mAccessPointsPreferenceCategory.addPreference(mAddWifiNetworkPreference); - setAdditionalSettingsSummaries(); + } - if (!hasAvailableAccessPoints) { + @Override + public void onNumSavedNetworksChanged() { + if (isFinishingOrDestroyed()) { + return; + } + setAdditionalSettingsSummaries(); + } + + @Override + public void onNumSavedSubscriptionsChanged() { + if (isFinishingOrDestroyed()) { + return; + } + setAdditionalSettingsSummaries(); + } + + /** + * Updates WifiEntries from {@link WifiPickerTracker#getWifiEntries()}. Adds a delay to have + * progress bar displayed before starting to modify entries. + */ + private void updateWifiEntryPreferencesDelayed() { + // Safeguard from some delayed event handling + if (getActivity() != null && !mIsRestricted + && mWifiPickerTracker.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { + final View view = getView(); + final Handler handler = view.getHandler(); + if (handler != null && handler.hasCallbacks(mUpdateWifiEntryPreferencesRunnable)) { + return; + } + setProgressBarVisible(true); + view.postDelayed(mUpdateWifiEntryPreferencesRunnable, 300); + } + } + + private void updateWifiEntryPreferences() { + // in case state has changed + if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) { + return; + } + + boolean hasAvailableWifiEntries = false; + mStatusMessagePreference.setVisible(false); + mWifiEntryPreferenceCategory.setVisible(true); + + final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry(); + mConnectedWifiEntryPreferenceCategory.setVisible(connectedEntry != null); + if (connectedEntry != null) { + final LongPressWifiEntryPreference connectedPref = + mConnectedWifiEntryPreferenceCategory.findPreference(connectedEntry.getKey()); + if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) { + mConnectedWifiEntryPreferenceCategory.removeAll(); + final ConnectedWifiEntryPreference pref = + new ConnectedWifiEntryPreference(getPrefContext(), connectedEntry, this); + pref.setKey(connectedEntry.getKey()); + pref.refresh(); + mConnectedWifiEntryPreferenceCategory.addPreference(pref); + pref.setOnPreferenceClickListener(preference -> { + if (connectedEntry.canSignIn()) { + connectedEntry.signIn(null /* callback */); + } else { + launchNetworkDetailsFragment(pref); + } + return true; + }); + pref.setOnGearClickListener(preference -> { + launchNetworkDetailsFragment(pref); + }); + + if (mClickedConnect) { + mClickedConnect = false; + scrollToPreference(mConnectedWifiEntryPreferenceCategory); + } + } + } else { + mConnectedWifiEntryPreferenceCategory.removeAll(); + } + + int index = 0; + cacheRemoveAllPrefs(mWifiEntryPreferenceCategory); + List wifiEntries = mWifiPickerTracker.getWifiEntries(); + for (WifiEntry wifiEntry : wifiEntries) { + hasAvailableWifiEntries = true; + + String key = wifiEntry.getKey(); + LongPressWifiEntryPreference pref = + (LongPressWifiEntryPreference) getCachedPreference(key); + if (pref != null) { + pref.setOrder(index++); + continue; + } + + pref = createLongPressWifiEntryPreference(wifiEntry); + pref.setKey(wifiEntry.getKey()); + pref.setOrder(index++); + pref.refresh(); + + if (wifiEntry.getHelpUriString() != null) { + pref.setOnButtonClickListener(preference -> { + openSubscriptionHelpPage(wifiEntry); + }); + } + mWifiEntryPreferenceCategory.addPreference(pref); + } + removeCachedPrefs(mWifiEntryPreferenceCategory); + + if (!hasAvailableWifiEntries) { setProgressBarVisible(true); Preference pref = new Preference(getPrefContext()); pref.setSelectable(false); pref.setSummary(R.string.wifi_empty_list_wifi_on); pref.setOrder(index++); pref.setKey(PREF_KEY_EMPTY_WIFI_LIST); - mAccessPointsPreferenceCategory.addPreference(pref); + mWifiEntryPreferenceCategory.addPreference(pref); } else { // Continuing showing progress bar for an additional delay to overlap with animation getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */); } + + mAddWifiNetworkPreference.setOrder(index++); + mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference); + setAdditionalSettingsSummaries(); } - @NonNull - private LongPressAccessPointPreference createLongPressAccessPointPreference( - AccessPoint accessPoint) { - return new LongPressAccessPointPreference(accessPoint, getPrefContext(), mUserBadgeCache, - false /* forSavedNetworks */, R.drawable.ic_wifi_signal_0, this); + private void launchNetworkDetailsFragment(LongPressWifiEntryPreference pref) { + final WifiEntry wifiEntry = pref.getWifiEntry(); + final Context context = getContext(); + final CharSequence title = + FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER) + ? wifiEntry.getTitle() + : context.getText(R.string.pref_title_network_details); + + final Bundle bundle = new Bundle(); + bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, wifiEntry.getKey()); + + new SubSettingLauncher(context) + .setTitleText(title) + .setDestination(WifiNetworkDetailsFragment2.class.getName()) + .setArguments(bundle) + .setSourceMetricsCategory(getMetricsCategory()) + .launch(); } - @NonNull @VisibleForTesting - ConnectedAccessPointPreference createConnectedAccessPointPreference( - AccessPoint accessPoint, Context context) { - return new ConnectedAccessPointPreference(accessPoint, context, mUserBadgeCache, - R.drawable.ic_wifi_signal_0, false /* forSavedNetworks */, this); - } - - /** - * Configure the ConnectedAccessPointPreferenceCategory and return true if the Category was - * shown. - */ - private boolean configureConnectedAccessPointPreferenceCategory( - List accessPoints) { - if (accessPoints.size() == 0) { - removeConnectedAccessPointPreference(); - return false; - } - - AccessPoint connectedAp = accessPoints.get(0); - if (!connectedAp.isActive()) { - removeConnectedAccessPointPreference(); - return false; - } - - // Is the preference category empty? - if (mConnectedAccessPointPreferenceCategory.getPreferenceCount() == 0) { - addConnectedAccessPointPreference(connectedAp); - return true; - } - - // Is the previous currently connected SSID different from the new one? - ConnectedAccessPointPreference preference = - (ConnectedAccessPointPreference) - (mConnectedAccessPointPreferenceCategory.getPreference(0)); - // The AccessPoints need to be the same reference to ensure that updates are reflected - // in the UI. - if (preference.getAccessPoint() != connectedAp) { - removeConnectedAccessPointPreference(); - addConnectedAccessPointPreference(connectedAp); - return true; - } - - // Else same AP is connected, simply refresh the connected access point preference - // (first and only access point in this category). - preference.refresh(); - // Update any potential changes to the connected network and ensure that the callback is - // registered after an onStop lifecycle event. - registerCaptivePortalNetworkCallback(getCurrentWifiNetwork(), preference); - return true; - } - - /** - * Creates a Preference for the given {@link AccessPoint} and adds it to the - * {@link #mConnectedAccessPointPreferenceCategory}. - */ - private void addConnectedAccessPointPreference(AccessPoint connectedAp) { - final ConnectedAccessPointPreference pref = - createConnectedAccessPointPreference(connectedAp, getPrefContext()); - registerCaptivePortalNetworkCallback(getCurrentWifiNetwork(), pref); - - // Launch details page or captive portal on click. - pref.setOnPreferenceClickListener( - preference -> { - pref.getAccessPoint().saveWifiState(pref.getExtras()); - if (mCaptivePortalNetworkCallback != null - && mCaptivePortalNetworkCallback.isCaptivePortal()) { - startCaptivePortalApp( - mCaptivePortalNetworkCallback.getNetwork()); - } else { - launchNetworkDetailsFragment(pref); - } - return true; - }); - - pref.setOnGearClickListener( - preference -> { - pref.getAccessPoint().saveWifiState(pref.getExtras()); - launchNetworkDetailsFragment(pref); - }); - - pref.refresh(); - - mConnectedAccessPointPreferenceCategory.addPreference(pref); - mConnectedAccessPointPreferenceCategory.setVisible(true); - if (mClickedConnect) { - mClickedConnect = false; - scrollToPreference(mConnectedAccessPointPreferenceCategory); - } - } - - private void registerCaptivePortalNetworkCallback( - Network wifiNetwork, ConnectedAccessPointPreference pref) { - if (wifiNetwork == null || pref == null) { - Log.w(TAG, "Network or Preference were null when registering callback."); - return; - } - - if (mCaptivePortalNetworkCallback != null - && mCaptivePortalNetworkCallback.isSameNetworkAndPreference(wifiNetwork, pref)) { - return; - } - - unregisterCaptivePortalNetworkCallback(); - - mCaptivePortalNetworkCallback = new CaptivePortalNetworkCallback(wifiNetwork, pref) { - @Override - public void onCaptivePortalCapabilityChanged() { - checkStartCaptivePortalApp(); - } - }; - mConnectivityManager.registerNetworkCallback( - new NetworkRequest.Builder() - .clearCapabilities() - .addTransportType(TRANSPORT_WIFI) - .build(), - mCaptivePortalNetworkCallback, - new Handler(Looper.getMainLooper())); - } - - private void unregisterCaptivePortalNetworkCallback() { - if (mCaptivePortalNetworkCallback != null) { - try { - mConnectivityManager.unregisterNetworkCallback(mCaptivePortalNetworkCallback); - } catch (RuntimeException e) { - Log.e(TAG, "Unregistering CaptivePortalNetworkCallback failed.", e); - } - mCaptivePortalNetworkCallback = null; - } + LongPressWifiEntryPreference createLongPressWifiEntryPreference(WifiEntry wifiEntry) { + return new LongPressWifiEntryPreference(getPrefContext(), wifiEntry, this); } private void launchAddNetworkFragment() { @@ -974,36 +832,15 @@ public class WifiSettings extends RestrictedSettingsFragment .launch(); } - private void launchNetworkDetailsFragment(ConnectedAccessPointPreference pref) { - final AccessPoint accessPoint = pref.getAccessPoint(); - final Context context = getContext(); - final CharSequence title = - FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER) - ? accessPoint.getTitle() - : context.getText(R.string.pref_title_network_details); - - new SubSettingLauncher(getContext()) - .setTitleText(title) - .setDestination(WifiNetworkDetailsFragment.class.getName()) - .setArguments(pref.getExtras()) - .setSourceMetricsCategory(getMetricsCategory()) - .launch(); + /** Removes all preferences and hide the {@link #mConnectedWifiEntryPreferenceCategory}. */ + private void removeConnectedWifiEntryPreference() { + mConnectedWifiEntryPreferenceCategory.removeAll(); + mConnectedWifiEntryPreferenceCategory.setVisible(false); } - private Network getCurrentWifiNetwork() { - return mWifiManager != null ? mWifiManager.getCurrentNetwork() : null; - } - - /** Removes all preferences and hide the {@link #mConnectedAccessPointPreferenceCategory}. */ - private void removeConnectedAccessPointPreference() { - mConnectedAccessPointPreferenceCategory.removeAll(); - mConnectedAccessPointPreferenceCategory.setVisible(false); - unregisterCaptivePortalNetworkCallback(); - } - - private void removeAccessPointPreference() { - mAccessPointsPreferenceCategory.removeAll(); - mAccessPointsPreferenceCategory.setVisible(false); + private void removeWifiEntryPreference() { + mWifiEntryPreferenceCategory.removeAll(); + mWifiEntryPreferenceCategory.setVisible(false); } @VisibleForTesting @@ -1013,36 +850,30 @@ public class WifiSettings extends RestrictedSettingsFragment ? R.string.wifi_configure_settings_preference_summary_wakeup_on : R.string.wifi_configure_settings_preference_summary_wakeup_off)); - final List savedNetworks = - WifiSavedConfigUtils.getAllConfigs(getContext(), mWifiManager); - final int numSavedNetworks = (savedNetworks != null) ? savedNetworks.size() : 0; - mSavedNetworksPreference.setVisible(numSavedNetworks > 0); - if (numSavedNetworks > 0) { + final int numSavedNetworks = mWifiPickerTracker.getNumSavedNetworks(); + final int numSavedSubscriptions = mWifiPickerTracker.getNumSavedSubscriptions(); + if (numSavedNetworks + numSavedSubscriptions > 0) { + mSavedNetworksPreference.setVisible(true); mSavedNetworksPreference.setSummary( - getSavedNetworkSettingsSummaryText(savedNetworks, numSavedNetworks)); + getSavedNetworkSettingsSummaryText(numSavedNetworks, numSavedSubscriptions)); + } else { + mSavedNetworksPreference.setVisible(false); } } private String getSavedNetworkSettingsSummaryText( - List savedNetworks, int numSavedNetworks) { - int numSavedPasspointNetworks = 0; - for (AccessPoint savedNetwork : savedNetworks) { - if (savedNetwork.isPasspointConfig() || savedNetwork.isPasspoint()) { - numSavedPasspointNetworks++; - } - } - final int numSavedNormalNetworks = numSavedNetworks - numSavedPasspointNetworks; - - if (numSavedNetworks == numSavedNormalNetworks) { + int numSavedNetworks, int numSavedSubscriptions) { + if (numSavedSubscriptions == 0) { return getResources().getQuantityString(R.plurals.wifi_saved_access_points_summary, - numSavedNormalNetworks, numSavedNormalNetworks); - } else if (numSavedNetworks == numSavedPasspointNetworks) { + numSavedNetworks, numSavedNetworks); + } else if (numSavedNetworks == 0) { return getResources().getQuantityString( R.plurals.wifi_saved_passpoint_access_points_summary, - numSavedPasspointNetworks, numSavedPasspointNetworks); + numSavedSubscriptions, numSavedSubscriptions); } else { + final int numTotalEntries = numSavedNetworks + numSavedSubscriptions; return getResources().getQuantityString(R.plurals.wifi_saved_all_access_points_summary, - numSavedNetworks, numSavedNetworks); + numTotalEntries, numTotalEntries); } } @@ -1073,8 +904,8 @@ public class WifiSettings extends RestrictedSettingsFragment .setSourceMetricsCategory(getMetricsCategory()) .launch(); mStatusMessagePreference.setText(title, description, clickListener); - removeConnectedAccessPointPreference(); - removeAccessPointPreference(); + removeConnectedWifiEntryPreference(); + removeWifiEntryPreference(); mStatusMessagePreference.setVisible(true); } @@ -1090,107 +921,11 @@ public class WifiSettings extends RestrictedSettingsFragment } } - /** - * Renames/replaces "Next" button when appropriate. "Next" button usually exists in - * Wifi setup screens, not in usual wifi settings screen. - * - * @param enabled true when the device is connected to a wifi network. - */ - private void changeNextButtonState(boolean enabled) { - if (mEnableNextOnConnection && hasNextButton()) { - getNextButton().setEnabled(enabled); - } - } - - @Override - public void onForget(WifiDialog dialog) { - forget(); - } - - @Override - public void onSubmit(WifiDialog dialog) { - if (mDialog != null) { - submit(mDialog.getController()); - } - } - - @Override - public void onScan(WifiDialog dialog, String ssid) { - // Launch QR code scanner to join a network. - startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), - REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); - } - - /* package */ void submit(WifiConfigController configController) { - - final WifiConfiguration config = configController.getConfig(); - - if (config == null) { - if (mSelectedAccessPoint != null - && mSelectedAccessPoint.isSaved()) { - connect(mSelectedAccessPoint.getConfig(), - true /* isSavedNetwork */, - CONNECT_SOURCE_UNSPECIFIED); - } - } else if (configController.getMode() == WifiConfigUiBase.MODE_MODIFY) { - mWifiManager.save(config, mSaveListener); - } else { - mWifiManager.save(config, mSaveListener); - if (mSelectedAccessPoint != null) { // Not an "Add network" - connect(config, false /* isSavedNetwork */, - CONNECT_SOURCE_UNSPECIFIED); - } - } - - mWifiTracker.resumeScanning(); - } - - /* package */ void forget() { - mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_FORGET); - if (!mSelectedAccessPoint.isSaved()) { - if (mSelectedAccessPoint.getNetworkInfo() != null && - mSelectedAccessPoint.getNetworkInfo().getState() != State.DISCONNECTED) { - // Network is active but has no network ID - must be ephemeral. - mWifiManager.disableEphemeralNetwork( - AccessPoint.convertToQuotedString(mSelectedAccessPoint.getSsidStr())); - } else { - // Should not happen, but a monkey seems to trigger it - Log.e(TAG, "Failed to forget invalid network " + mSelectedAccessPoint.getConfig()); - return; - } - } else if (mSelectedAccessPoint.getConfig().isPasspoint()) { - try { - mWifiManager.removePasspointConfiguration(mSelectedAccessPoint.getConfig().FQDN); - } catch (IllegalArgumentException e) { - Log.e(TAG, "Failed to remove Passpoint configuration with error: " + e); - return; - } - } else { - mWifiManager.forget(mSelectedAccessPoint.getConfig().networkId, mForgetListener); - } - - mWifiTracker.resumeScanning(); - - // We need to rename/replace "Next" button in wifi setup context. - changeNextButtonState(false); - } - - protected void connect(final WifiConfiguration config, - boolean isSavedNetwork, @ConnectSource int connectSource) { - // Log subtype if configuration is a saved network. - mMetricsFeatureProvider.action(getContext(), SettingsEnums.ACTION_WIFI_CONNECT, - isSavedNetwork); - mConnectSource = connectSource; - mWifiManager.connect(config, mConnectListener); - mClickedConnect = true; - } - @VisibleForTesting void handleAddNetworkRequest(int result, Intent data) { if (result == Activity.RESULT_OK) { handleAddNetworkSubmitEvent(data); } - mWifiTracker.resumeScanning(); } private void handleAddNetworkSubmitEvent(Intent data) { @@ -1205,8 +940,6 @@ public class WifiSettings extends RestrictedSettingsFragment * Called when "add network" button is pressed. */ private void onAddNetworkPressed() { - // No exact access point is selected. - mSelectedAccessPoint = null; launchAddNetworkFragment(); } @@ -1215,91 +948,87 @@ public class WifiSettings extends RestrictedSettingsFragment return R.string.help_url_wifi; } - @Override - public void onAccessPointChanged(final AccessPoint accessPoint) { - Log.d(TAG, "onAccessPointChanged (singular) callback initiated"); - View view = getView(); - if (view != null) { - view.post(new Runnable() { - @Override - public void run() { - Object tag = accessPoint.getTag(); - if (tag != null) { - ((AccessPointPreference) tag).refresh(); - } - } - }); - } - } - - @Override - public void onLevelChanged(AccessPoint accessPoint) { - ((AccessPointPreference) accessPoint.getTag()).onLevelChanged(); - } - - private void handleConfigNetworkSubmitEvent(Intent data) { - final WifiConfiguration wifiConfiguration = data.getParcelableExtra( - ConfigureAccessPointFragment.NETWORK_CONFIG_KEY); - if (wifiConfiguration != null) { - mWifiManager.save(wifiConfiguration, mSaveListener); - - if (mSelectedAccessPoint != null) { - connect(wifiConfiguration, false /*isSavedNetwork*/, - CONNECT_SOURCE_UNSPECIFIED); - } - mWifiTracker.resumeScanning(); - } - } - - private void launchConfigNewNetworkFragment(AccessPoint accessPoint, int dialogMode, - Bundle bundleForArguments) { - mDialogMode = dialogMode; - final CharSequence title = accessPoint.getTitle(); - new SubSettingLauncher(getContext()) - .setTitleText(title) - .setDestination(ConfigureAccessPointFragment.class.getName()) - .setArguments(bundleForArguments) - .setSourceMetricsCategory(getMetricsCategory()) - .setResultListener(this, CONFIG_NETWORK_REQUEST) - .launch(); - } - /** - * Starts the captive portal for current network if it's been clicked from the available - * networks (or contextual menu). We only do it *once* for a picked network, to avoid connecting - * again on bg/fg or if user dismisses Captive Portal before connecting (otherwise, coming back - * to this screen while connected to the same network but not signed in would open CP again). + * Renames/replaces "Next" button when appropriate. "Next" button usually exists in + * Wi-Fi setup screens, not in usual wifi settings screen. + * + * @param enabled true when the device is connected to a wifi network. */ - private void checkStartCaptivePortalApp() { - Network currentNetwork = getCurrentWifiNetwork(); - if (mCaptivePortalNetworkCallback == null || currentNetwork == null - || !currentNetwork.equals(mCaptivePortalNetworkCallback.getNetwork()) - || !mCaptivePortalNetworkCallback.isCaptivePortal()) { - return; + @VisibleForTesting + void changeNextButtonState(boolean enabled) { + if (mEnableNextOnConnection && hasNextButton()) { + getNextButton().setEnabled(enabled); } - - if (mConnectSource != CONNECT_SOURCE_NETWORK_LIST_ITEM_CLICK - && mConnectSource != CONNECT_SOURCE_NETWORK_MENU_ITEM_CLICK) { - return; - } - - if (mLastNetworkCaptivePortalAppStarted != null - && mLastNetworkCaptivePortalAppStarted.equals(currentNetwork)) { - // We already auto-opened CP for same network - return; - } - - startCaptivePortalApp(currentNetwork); } - private void startCaptivePortalApp(Network network) { - if (mConnectivityManager == null || network == null) { - return; - } - mLastNetworkCaptivePortalAppStarted = network; - mConnectivityManager.startCaptivePortalApp(network); + @Override + public void onForget(WifiDialog2 dialog) { + forget(dialog.getWifiEntry()); } + @Override + public void onSubmit(WifiDialog2 dialog) { + final int dialogMode = dialog.getMode(); + final WifiConfiguration config = dialog.getController().getConfig(); + final WifiEntry wifiEntry = dialog.getWifiEntry(); + + if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) { + if (config == null) { + Toast.makeText(getContext(), R.string.wifi_failed_save_message, + Toast.LENGTH_SHORT).show(); + } else { + mWifiManager.save(config, mSaveListener); + } + } else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT + || (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) { + if (config == null) { + connect(wifiEntry, false /* editIfNoConfig */, + false /* fullScreenEdit*/); + } else { + mWifiManager.connect(config, new WifiConnectActionListener()); + } + } + } + + @Override + public void onScan(WifiDialog2 dialog, String ssid) { + // Launch QR code scanner to join a network. + startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), + REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); + } + + private void forget(WifiEntry wifiEntry) { + mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_FORGET); + wifiEntry.forget(null /* callback */); + } + + @VisibleForTesting + void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) { + mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT, + wifiEntry.isSaved()); + + // If it's an unsaved secure WifiEntry, it will callback + // ConnectCallback#onConnectResult with ConnectCallback#CONNECT_STATUS_FAILURE_NO_CONFIG + wifiEntry.connect(new WifiEntryConnectCallback(wifiEntry, editIfNoConfig, + fullScreenEdit)); + } + + private class WifiConnectActionListener implements WifiManager.ActionListener { + @Override + public void onSuccess() { + mClickedConnect = true; + } + + @Override + public void onFailure(int reason) { + if (isFinishingOrDestroyed()) { + return; + } + Toast.makeText(getContext(), R.string.wifi_failed_connect_message, Toast.LENGTH_SHORT) + .show(); + } + }; + public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = new BaseSearchIndexProvider(R.xml.wifi_settings) { @Override @@ -1317,4 +1046,86 @@ public class WifiSettings extends RestrictedSettingsFragment return keys; } }; + + private class WifiEntryConnectCallback implements ConnectCallback { + final WifiEntry mConnectWifiEntry; + final boolean mEditIfNoConfig; + final boolean mFullScreenEdit; + + WifiEntryConnectCallback(WifiEntry connectWifiEntry, boolean editIfNoConfig, + boolean fullScreenEdit) { + mConnectWifiEntry = connectWifiEntry; + mEditIfNoConfig = editIfNoConfig; + mFullScreenEdit = fullScreenEdit; + } + + @Override + public void onConnectResult(@ConnectStatus int status) { + if (isFinishingOrDestroyed()) { + return; + } + + if (status == ConnectCallback.CONNECT_STATUS_SUCCESS) { + mClickedConnect = true; + } else if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) { + if (mEditIfNoConfig) { + // Edit an unsaved secure Wi-Fi network. + if (mFullScreenEdit) { + launchConfigNewNetworkFragment(mConnectWifiEntry); + } else { + showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_CONNECT); + } + } + } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) { + Toast.makeText(getContext(), R.string.wifi_failed_connect_message, + Toast.LENGTH_SHORT).show(); + } + } + } + + private void launchConfigNewNetworkFragment(WifiEntry wifiEntry) { + final Bundle bundle = new Bundle(); + bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, + wifiEntry.getKey()); + new SubSettingLauncher(getContext()) + .setTitleText(wifiEntry.getTitle()) + .setDestination(ConfigureWifiEntryFragment.class.getName()) + .setArguments(bundle) + .setSourceMetricsCategory(getMetricsCategory()) + .setResultListener(WifiSettings.this, CONFIG_NETWORK_REQUEST) + .launch(); + } + + /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ + private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { + WifiConfiguration config = wifiEntry.getWifiConfiguration(); + if (config == null) { + return false; + } + WifiConfiguration.NetworkSelectionStatus networkStatus = + config.getNetworkSelectionStatus(); + if (networkStatus == null + || networkStatus.getNetworkSelectionStatus() == NETWORK_SELECTION_ENABLED) { + return false; + } + int reason = networkStatus.getNetworkSelectionDisableReason(); + return WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD == reason; + } + + @VisibleForTesting + void openSubscriptionHelpPage(WifiEntry wifiEntry) { + final Intent intent = getHelpIntent(getContext(), wifiEntry.getHelpUriString()); + if (intent != null) { + try { + startActivityForResult(intent, MANAGE_SUBSCRIPTION); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Activity was not found for intent, " + intent.toString()); + } + } + } + + @VisibleForTesting + Intent getHelpIntent(Context context, String helpUrlString) { + return HelpUtils.getHelpIntent(context, helpUrlString, context.getClass().getName()); + } } diff --git a/src/com/android/settings/wifi/WifiSettings2.java b/src/com/android/settings/wifi/WifiSettings2.java deleted file mode 100644 index 3b18f5a4fc7..00000000000 --- a/src/com/android/settings/wifi/WifiSettings2.java +++ /dev/null @@ -1,1131 +0,0 @@ -/* - * Copyright (C) 2019 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 static android.net.wifi.WifiConfiguration.NetworkSelectionStatus.NETWORK_SELECTION_ENABLED; -import static android.os.UserManager.DISALLOW_CONFIG_WIFI; - -import android.app.Activity; -import android.app.Dialog; -import android.app.settings.SettingsEnums; -import android.content.ActivityNotFoundException; -import android.content.ContentResolver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.net.ConnectivityManager; -import android.net.NetworkScoreManager; -import android.net.NetworkTemplate; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerThread; -import android.os.Looper; -import android.os.PowerManager; -import android.os.Process; -import android.os.SimpleClock; -import android.os.SystemClock; -import android.provider.Settings; -import android.text.TextUtils; -import android.util.FeatureFlagUtils; -import android.util.Log; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Toast; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceCategory; -import androidx.preference.PreferenceScreen; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.settings.LinkifyUtils; -import com.android.settings.R; -import com.android.settings.RestrictedSettingsFragment; -import com.android.settings.SettingsActivity; -import com.android.settings.core.FeatureFlags; -import com.android.settings.core.SubSettingLauncher; -import com.android.settings.datausage.DataUsagePreference; -import com.android.settings.datausage.DataUsageUtils; -import com.android.settings.location.ScanningSettings; -import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.widget.SwitchBarController; -import com.android.settings.wifi.details2.WifiNetworkDetailsFragment2; -import com.android.settings.wifi.dpp.WifiDppUtils; -import com.android.settingslib.HelpUtils; -import com.android.settingslib.RestrictedLockUtils; -import com.android.settingslib.RestrictedLockUtilsInternal; -import com.android.settingslib.search.Indexable; -import com.android.settingslib.search.SearchIndexable; -import com.android.settingslib.wifi.LongPressWifiEntryPreference; -import com.android.settingslib.wifi.WifiSavedConfigUtils; -import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiEntry.ConnectCallback; -import com.android.wifitrackerlib.WifiPickerTracker; - -import java.time.Clock; -import java.time.ZoneOffset; -import java.util.List; -import java.util.Optional; - -/** - * UI for Wi-Fi settings screen - */ -@SearchIndexable -public class WifiSettings2 extends RestrictedSettingsFragment - implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback, - WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener { - - private static final String TAG = "WifiSettings2"; - - // IDs of context menu - static final int MENU_ID_CONNECT = Menu.FIRST + 1; - @VisibleForTesting - static final int MENU_ID_DISCONNECT = Menu.FIRST + 2; - @VisibleForTesting - static final int MENU_ID_FORGET = Menu.FIRST + 3; - static final int MENU_ID_MODIFY = Menu.FIRST + 4; - - // Max age of tracked WifiEntries - private static final long MAX_SCAN_AGE_MILLIS = 15_000; - // Interval between initiating WifiPickerTracker scans - private static final long SCAN_INTERVAL_MILLIS = 10_000; - - @VisibleForTesting - static final int ADD_NETWORK_REQUEST = 2; - static final int CONFIG_NETWORK_REQUEST = 3; - static final int MANAGE_SUBSCRIPTION = 4; - - private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list"; - // TODO(b/70983952): Rename these to use WifiEntry instead of AccessPoint. - private static final String PREF_KEY_CONNECTED_ACCESS_POINTS = "connected_access_point"; - private static final String PREF_KEY_ACCESS_POINTS = "access_points"; - private static final String PREF_KEY_CONFIGURE_WIFI_SETTINGS = "configure_wifi_settings"; - private static final String PREF_KEY_SAVED_NETWORKS = "saved_networks"; - private static final String PREF_KEY_STATUS_MESSAGE = "wifi_status_message"; - @VisibleForTesting - static final String PREF_KEY_DATA_USAGE = "wifi_data_usage"; - - private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0; - - public static final int WIFI_DIALOG_ID = 1; - - // Instance state keys - private static final String SAVE_DIALOG_MODE = "dialog_mode"; - private static final String SAVE_DIALOG_WIFIENTRY_KEY = "wifi_ap_key"; - - // Cache at onCreateContextMenu and use at onContextItemSelected. Don't use it in other methods. - private WifiEntry mSelectedWifiEntry; - - // Save the dialog details - private int mDialogMode; - private String mDialogWifiEntryKey; - private WifiEntry mDialogWifiEntry; - - // This boolean extra specifies whether to enable the Next button when connected. Used by - // account creation outside of setup wizard. - private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect"; - - // Enable the Next button when a Wi-Fi network is connected. - private boolean mEnableNextOnConnection; - - // This string extra specifies a network to open the connect dialog on, so the user can enter - // network credentials. This is used by quick settings for secured networks, among other - // things. - private static final String EXTRA_START_CONNECT_SSID = "wifi_start_connect_ssid"; - private String mOpenSsid; - - private static boolean isVerboseLoggingEnabled() { - return WifiPickerTracker.isVerboseLoggingEnabled(); - } - - private final Runnable mUpdateWifiEntryPreferencesRunnable = () -> { - updateWifiEntryPreferences(); - }; - private final Runnable mHideProgressBarRunnable = () -> { - setProgressBarVisible(false); - }; - - protected WifiManager mWifiManager; - private WifiManager.ActionListener mConnectListener; - private WifiManager.ActionListener mSaveListener; - private WifiManager.ActionListener mForgetListener; - - /** - * The state of {@link #isUiRestricted()} at {@link #onCreate(Bundle)}}. This is neccesary to - * ensure that behavior is consistent if {@link #isUiRestricted()} changes. It could be changed - * by the Test DPC tool in AFW mode. - */ - private boolean mIsRestricted; - - private WifiEnabler mWifiEnabler; - - // Worker thread used for WifiPickerTracker work - private HandlerThread mWorkerThread; - - @VisibleForTesting - WifiPickerTracker mWifiPickerTracker; - - private WifiDialog2 mDialog; - - private View mProgressHeader; - - private PreferenceCategory mConnectedWifiEntryPreferenceCategory; - private PreferenceCategory mWifiEntryPreferenceCategory; - @VisibleForTesting - AddWifiNetworkPreference mAddWifiNetworkPreference; - @VisibleForTesting - Preference mConfigureWifiSettingsPreference; - @VisibleForTesting - Preference mSavedNetworksPreference; - @VisibleForTesting - DataUsagePreference mDataUsagePreference; - private LinkablePreference mStatusMessagePreference; - - /** - * Tracks whether the user initiated a connection via clicking in order to autoscroll to the - * network once connected. - */ - private boolean mClickedConnect; - - public WifiSettings2() { - super(DISALLOW_CONFIG_WIFI); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - final Activity activity = getActivity(); - if (activity != null) { - mProgressHeader = setPinnedHeaderView(R.layout.progress_header) - .findViewById(R.id.progress_bar_animation); - setProgressBarVisible(false); - } - ((SettingsActivity) activity).getSwitchBar().setSwitchBarText( - R.string.wifi_settings_master_switch_title, - R.string.wifi_settings_master_switch_title); - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - // TODO(b/37429702): Add animations and preference comparator back after initial screen is - // loaded (ODR). - setAnimationAllowed(false); - - addPreferences(); - - mIsRestricted = isUiRestricted(); - } - - private void addPreferences() { - addPreferencesFromResource(R.xml.wifi_settings2); - - mConnectedWifiEntryPreferenceCategory = findPreference(PREF_KEY_CONNECTED_ACCESS_POINTS); - mWifiEntryPreferenceCategory = findPreference(PREF_KEY_ACCESS_POINTS); - mConfigureWifiSettingsPreference = findPreference(PREF_KEY_CONFIGURE_WIFI_SETTINGS); - mSavedNetworksPreference = findPreference(PREF_KEY_SAVED_NETWORKS); - mAddWifiNetworkPreference = new AddWifiNetworkPreference(getPrefContext()); - mStatusMessagePreference = findPreference(PREF_KEY_STATUS_MESSAGE); - mDataUsagePreference = findPreference(PREF_KEY_DATA_USAGE); - mDataUsagePreference.setVisible(DataUsageUtils.hasWifiRadio(getContext())); - mDataUsagePreference.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), - 0 /*subId*/, - null /*service*/); - } - - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - - final Context context = getContext(); - mWorkerThread = new HandlerThread(TAG + - "{" + Integer.toHexString(System.identityHashCode(this)) + "}", - Process.THREAD_PRIORITY_BACKGROUND); - mWorkerThread.start(); - final Clock elapsedRealtimeClock = new SimpleClock(ZoneOffset.UTC) { - @Override - public long millis() { - return SystemClock.elapsedRealtime(); - } - }; - mWifiPickerTracker = new WifiPickerTracker(getSettingsLifecycle(), context, - context.getSystemService(WifiManager.class), - context.getSystemService(ConnectivityManager.class), - context.getSystemService(NetworkScoreManager.class), - new Handler(Looper.getMainLooper()), - mWorkerThread.getThreadHandler(), - elapsedRealtimeClock, - MAX_SCAN_AGE_MILLIS, - SCAN_INTERVAL_MILLIS, - this); - - final Activity activity = getActivity(); - - if (activity != null) { - mWifiManager = getActivity().getSystemService(WifiManager.class); - } - - mConnectListener = new WifiConnectListener(getActivity()); - - mSaveListener = new WifiManager.ActionListener() { - @Override - public void onSuccess() { - } - - @Override - public void onFailure(int reason) { - Activity activity = getActivity(); - if (activity != null) { - Toast.makeText(activity, - R.string.wifi_failed_save_message, - Toast.LENGTH_SHORT).show(); - } - } - }; - - mForgetListener = new WifiManager.ActionListener() { - @Override - public void onSuccess() { - } - - @Override - public void onFailure(int reason) { - Activity activity = getActivity(); - if (activity != null) { - Toast.makeText(activity, - R.string.wifi_failed_forget_message, - Toast.LENGTH_SHORT).show(); - } - } - }; - registerForContextMenu(getListView()); - setHasOptionsMenu(true); - - if (savedInstanceState != null) { - mDialogMode = savedInstanceState.getInt(SAVE_DIALOG_MODE); - mDialogWifiEntryKey = savedInstanceState.getString(SAVE_DIALOG_WIFIENTRY_KEY); - } - - // If we're supposed to enable/disable the Next button based on our current connection - // state, start it off in the right state. - final Intent intent = getActivity().getIntent(); - mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false); - - if (intent.hasExtra(EXTRA_START_CONNECT_SSID)) { - mOpenSsid = intent.getStringExtra(EXTRA_START_CONNECT_SSID); - } - } - - @Override - public void onDestroyView() { - if (mWifiEnabler != null) { - mWifiEnabler.teardownSwitchController(); - } - mWorkerThread.quit(); - - super.onDestroyView(); - } - - @Override - public void onStart() { - super.onStart(); - - mWifiEnabler = createWifiEnabler(); - - if (mIsRestricted) { - restrictUi(); - } - } - - private void restrictUi() { - if (!isUiRestrictedByOnlyAdmin()) { - getEmptyTextView().setText(R.string.wifi_empty_list_user_restricted); - } - getPreferenceScreen().removeAll(); - } - - /** - * @return new WifiEnabler - */ - private WifiEnabler createWifiEnabler() { - final SettingsActivity activity = (SettingsActivity) getActivity(); - return new WifiEnabler(activity, new SwitchBarController(activity.getSwitchBar()), - mMetricsFeatureProvider); - } - - @Override - public void onResume() { - final Activity activity = getActivity(); - super.onResume(); - - // Because RestrictedSettingsFragment's onResume potentially requests authorization, - // which changes the restriction state, recalculate it. - final boolean alreadyImmutablyRestricted = mIsRestricted; - mIsRestricted = isUiRestricted(); - if (!alreadyImmutablyRestricted && mIsRestricted) { - restrictUi(); - } - - if (mWifiEnabler != null) { - mWifiEnabler.resume(activity); - } - - changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null); - } - - @Override - public void onPause() { - super.onPause(); - if (mWifiEnabler != null) { - mWifiEnabler.pause(); - } - } - - @Override - public void onStop() { - getView().removeCallbacks(mUpdateWifiEntryPreferencesRunnable); - getView().removeCallbacks(mHideProgressBarRunnable); - super.onStop(); - } - - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - - if (requestCode == ADD_NETWORK_REQUEST) { - handleAddNetworkRequest(resultCode, data); - return; - } else if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) { - if (resultCode == Activity.RESULT_OK) { - if (mDialog != null) { - mDialog.dismiss(); - } - } - return; - } else if (requestCode == CONFIG_NETWORK_REQUEST) { - if (resultCode == Activity.RESULT_OK) { - final WifiConfiguration wifiConfiguration = data.getParcelableExtra( - ConfigureWifiEntryFragment.NETWORK_CONFIG_KEY); - if (wifiConfiguration != null) { - mWifiManager.connect(wifiConfiguration, - new WifiConnectActionListener()); - } - } - return; - } else if (requestCode == MANAGE_SUBSCRIPTION) { - //Do nothing - return; - } - - final boolean formerlyRestricted = mIsRestricted; - mIsRestricted = isUiRestricted(); - if (formerlyRestricted && !mIsRestricted - && getPreferenceScreen().getPreferenceCount() == 0) { - // De-restrict the ui - addPreferences(); - } - } - - @Override - protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { - final RecyclerView.Adapter adapter = super.onCreateAdapter(preferenceScreen); - adapter.setHasStableIds(true); - return adapter; - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.WIFI; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - // If dialog has been shown, save its state. - if (mDialog != null) { - outState.putInt(SAVE_DIALOG_MODE, mDialogMode); - outState.putString(SAVE_DIALOG_WIFIENTRY_KEY, mDialogWifiEntryKey); - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) { - Preference preference = (Preference) view.getTag(); - if (!(preference instanceof LongPressWifiEntryPreference)) { - // Do nothing. - return; - } - - // Cache the WifiEntry for onContextItemSelected. Don't use it in other methods. - mSelectedWifiEntry = ((LongPressWifiEntryPreference) preference).getWifiEntry(); - - menu.setHeaderTitle(mSelectedWifiEntry.getTitle()); - if (mSelectedWifiEntry.canConnect()) { - menu.add(Menu.NONE, MENU_ID_CONNECT, 0 /* order */, R.string.wifi_connect); - } - - if (mSelectedWifiEntry.canDisconnect()) { - menu.add(Menu.NONE, MENU_ID_DISCONNECT, 0 /* order */, - R.string.wifi_disconnect_button_text); - } - - // "forget" for normal saved network. And "disconnect" for ephemeral network because it - // could only be disconnected and be put in blacklists so it won't be used again. - if (canForgetNetwork()) { - menu.add(Menu.NONE, MENU_ID_FORGET, 0 /* order */, R.string.forget); - } - - WifiConfiguration config = mSelectedWifiEntry.getWifiConfiguration(); - // Some configs are ineditable - if (WifiUtils.isNetworkLockedDown(getActivity(), config)) { - return; - } - - if (mSelectedWifiEntry.isSaved() && mSelectedWifiEntry.getConnectedState() - != WifiEntry.CONNECTED_STATE_CONNECTED) { - menu.add(Menu.NONE, MENU_ID_MODIFY, 0 /* order */, R.string.wifi_modify); - } - } - - private boolean canForgetNetwork() { - return mSelectedWifiEntry.canForget() && !WifiUtils.isNetworkLockedDown(getActivity(), - mSelectedWifiEntry.getWifiConfiguration()); - } - - @Override - public boolean onContextItemSelected(MenuItem item) { - switch (item.getItemId()) { - case MENU_ID_CONNECT: - connect(mSelectedWifiEntry, true /* editIfNoConfig */, false /* fullScreenEdit */); - return true; - case MENU_ID_DISCONNECT: - mSelectedWifiEntry.disconnect(null /* callback */); - return true; - case MENU_ID_FORGET: - forget(mSelectedWifiEntry); - return true; - case MENU_ID_MODIFY: - showDialog(mSelectedWifiEntry, WifiConfigUiBase2.MODE_MODIFY); - return true; - default: - return super.onContextItemSelected(item); - } - } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - // If the preference has a fragment set, open that - if (preference.getFragment() != null) { - preference.setOnPreferenceClickListener(null); - return super.onPreferenceTreeClick(preference); - } - - if (preference instanceof LongPressWifiEntryPreference) { - final WifiEntry selectedEntry = - ((LongPressWifiEntryPreference) preference).getWifiEntry(); - - if (selectedEntry.shouldEditBeforeConnect()) { - launchConfigNewNetworkFragment(selectedEntry); - return true; - } - - connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */); - } else if (preference == mAddWifiNetworkPreference) { - onAddNetworkPressed(); - } else { - return super.onPreferenceTreeClick(preference); - } - return true; - } - - private void showDialog(WifiEntry wifiEntry, int dialogMode) { - if (WifiUtils.isNetworkLockedDown(getActivity(), wifiEntry.getWifiConfiguration()) - && wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) { - RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getActivity(), - RestrictedLockUtilsInternal.getDeviceOwner(getActivity())); - return; - } - - if (mDialog != null) { - removeDialog(WIFI_DIALOG_ID); - mDialog = null; - } - - // Save the access point and edit mode - mDialogWifiEntry = wifiEntry; - mDialogWifiEntryKey = wifiEntry.getKey(); - mDialogMode = dialogMode; - - showDialog(WIFI_DIALOG_ID); - } - - @Override - public Dialog onCreateDialog(int dialogId) { - switch (dialogId) { - case WIFI_DIALOG_ID: - // modify network - mDialog = WifiDialog2 - .createModal(getActivity(), this, mDialogWifiEntry, mDialogMode); - return mDialog; - default: - return super.onCreateDialog(dialogId); - } - } - - @Override - public void onDialogShowing() { - super.onDialogShowing(); - setOnDismissListener(this); - } - - @Override - public void onDismiss(DialogInterface dialog) { - // We don't keep any dialog object when dialog was dismissed. - mDialog = null; - mDialogWifiEntry = null; - mDialogWifiEntryKey = null; - } - - @Override - public int getDialogMetricsCategory(int dialogId) { - switch (dialogId) { - case WIFI_DIALOG_ID: - return SettingsEnums.DIALOG_WIFI_AP_EDIT; - default: - return 0; - } - } - - /** Called when the state of Wifi has changed. */ - @Override - public void onWifiStateChanged() { - if (mIsRestricted) { - return; - } - final int wifiState = mWifiPickerTracker.getWifiState(); - - if (isVerboseLoggingEnabled()) { - Log.i(TAG, "onWifiStateChanged called with wifi state: " + wifiState); - } - - switch (wifiState) { - case WifiManager.WIFI_STATE_ENABLED: - updateWifiEntryPreferences(); - break; - - case WifiManager.WIFI_STATE_ENABLING: - removeConnectedWifiEntryPreference(); - removeWifiEntryPreference(); - addMessagePreference(R.string.wifi_starting); - setProgressBarVisible(true); - break; - - case WifiManager.WIFI_STATE_DISABLING: - removeConnectedWifiEntryPreference(); - removeWifiEntryPreference(); - addMessagePreference(R.string.wifi_stopping); - break; - - case WifiManager.WIFI_STATE_DISABLED: - setOffMessage(); - setAdditionalSettingsSummaries(); - setProgressBarVisible(false); - mClickedConnect = false; - break; - } - } - - @Override - public void onWifiEntriesChanged() { - updateWifiEntryPreferencesDelayed(); - changeNextButtonState(mWifiPickerTracker.getConnectedWifiEntry() != null); - - // Edit the Wi-Fi network of specified SSID. - if (mOpenSsid != null) { - Optional matchedWifiEntry = mWifiPickerTracker.getWifiEntries().stream() - .filter(wifiEntry -> TextUtils.equals(mOpenSsid, wifiEntry.getSsid())) - .filter(wifiEntry -> wifiEntry.getSecurity() != WifiEntry.SECURITY_NONE - && wifiEntry.getSecurity() != WifiEntry.SECURITY_OWE) - .filter(wifiEntry -> !wifiEntry.isSaved() - || isDisabledByWrongPassword(wifiEntry)) - .findFirst(); - if (matchedWifiEntry.isPresent()) { - mOpenSsid = null; - launchConfigNewNetworkFragment(matchedWifiEntry.get()); - } - } - } - - @Override - public void onNumSavedNetworksChanged() { - if (isFinishingOrDestroyed()) { - return; - } - setAdditionalSettingsSummaries(); - } - - @Override - public void onNumSavedSubscriptionsChanged() { - if (isFinishingOrDestroyed()) { - return; - } - setAdditionalSettingsSummaries(); - } - - /** - * Updates WifiEntries from {@link WifiPickerTracker#getWifiEntries()}. Adds a delay to have - * progress bar displayed before starting to modify entries. - */ - private void updateWifiEntryPreferencesDelayed() { - // Safeguard from some delayed event handling - if (getActivity() != null && !mIsRestricted && - mWifiPickerTracker.getWifiState() == WifiManager.WIFI_STATE_ENABLED) { - final View view = getView(); - final Handler handler = view.getHandler(); - if (handler != null && handler.hasCallbacks(mUpdateWifiEntryPreferencesRunnable)) { - return; - } - setProgressBarVisible(true); - view.postDelayed(mUpdateWifiEntryPreferencesRunnable, 300); - } - } - - private void updateWifiEntryPreferences() { - // in case state has changed - if (mWifiPickerTracker.getWifiState() != WifiManager.WIFI_STATE_ENABLED) { - return; - } - - boolean hasAvailableWifiEntries = false; - mStatusMessagePreference.setVisible(false); - mWifiEntryPreferenceCategory.setVisible(true); - - final WifiEntry connectedEntry = mWifiPickerTracker.getConnectedWifiEntry(); - mConnectedWifiEntryPreferenceCategory.setVisible(connectedEntry != null); - if (connectedEntry != null) { - final LongPressWifiEntryPreference connectedPref = - mConnectedWifiEntryPreferenceCategory.findPreference(connectedEntry.getKey()); - if (connectedPref == null || connectedPref.getWifiEntry() != connectedEntry) { - mConnectedWifiEntryPreferenceCategory.removeAll(); - final ConnectedWifiEntryPreference pref = - new ConnectedWifiEntryPreference(getPrefContext(), connectedEntry, this); - pref.setKey(connectedEntry.getKey()); - pref.refresh(); - mConnectedWifiEntryPreferenceCategory.addPreference(pref); - pref.setOnPreferenceClickListener(preference -> { - if (connectedEntry.canSignIn()) { - connectedEntry.signIn(null /* callback */); - } else { - launchNetworkDetailsFragment(pref); - } - return true; - }); - pref.setOnGearClickListener(preference -> { - launchNetworkDetailsFragment(pref); - }); - - if (mClickedConnect) { - mClickedConnect = false; - scrollToPreference(mConnectedWifiEntryPreferenceCategory); - } - } - } else { - mConnectedWifiEntryPreferenceCategory.removeAll(); - } - - int index = 0; - cacheRemoveAllPrefs(mWifiEntryPreferenceCategory); - List wifiEntries = mWifiPickerTracker.getWifiEntries(); - for (WifiEntry wifiEntry : wifiEntries) { - hasAvailableWifiEntries = true; - - String key = wifiEntry.getKey(); - LongPressWifiEntryPreference pref = - (LongPressWifiEntryPreference) getCachedPreference(key); - if (pref != null) { - pref.setOrder(index++); - continue; - } - - pref = createLongPressWifiEntryPreference(wifiEntry); - pref.setKey(wifiEntry.getKey()); - pref.setOrder(index++); - pref.refresh(); - - if (wifiEntry.getHelpUriString() != null) { - pref.setOnButtonClickListener(preference -> { - openSubscriptionHelpPage(wifiEntry); - }); - } - mWifiEntryPreferenceCategory.addPreference(pref); - } - removeCachedPrefs(mWifiEntryPreferenceCategory); - - if (!hasAvailableWifiEntries) { - setProgressBarVisible(true); - Preference pref = new Preference(getPrefContext()); - pref.setSelectable(false); - pref.setSummary(R.string.wifi_empty_list_wifi_on); - pref.setOrder(index++); - pref.setKey(PREF_KEY_EMPTY_WIFI_LIST); - mWifiEntryPreferenceCategory.addPreference(pref); - } else { - // Continuing showing progress bar for an additional delay to overlap with animation - getView().postDelayed(mHideProgressBarRunnable, 1700 /* delay millis */); - } - - mAddWifiNetworkPreference.setOrder(index++); - mWifiEntryPreferenceCategory.addPreference(mAddWifiNetworkPreference); - setAdditionalSettingsSummaries(); - } - - private void launchNetworkDetailsFragment(LongPressWifiEntryPreference pref) { - final WifiEntry wifiEntry = pref.getWifiEntry(); - final Context context = getContext(); - final CharSequence title = - FeatureFlagUtils.isEnabled(context, FeatureFlags.WIFI_DETAILS_DATAUSAGE_HEADER) - ? wifiEntry.getTitle() - : context.getText(R.string.pref_title_network_details); - - final Bundle bundle = new Bundle(); - bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, wifiEntry.getKey()); - - new SubSettingLauncher(context) - .setTitleText(title) - .setDestination(WifiNetworkDetailsFragment2.class.getName()) - .setArguments(bundle) - .setSourceMetricsCategory(getMetricsCategory()) - .launch(); - } - - @VisibleForTesting - LongPressWifiEntryPreference createLongPressWifiEntryPreference(WifiEntry wifiEntry) { - return new LongPressWifiEntryPreference(getPrefContext(), wifiEntry, this); - } - - private void launchAddNetworkFragment() { - new SubSettingLauncher(getContext()) - .setTitleRes(R.string.wifi_add_network) - .setDestination(AddNetworkFragment.class.getName()) - .setSourceMetricsCategory(getMetricsCategory()) - .setResultListener(this, ADD_NETWORK_REQUEST) - .launch(); - } - - /** Removes all preferences and hide the {@link #mConnectedWifiEntryPreferenceCategory}. */ - private void removeConnectedWifiEntryPreference() { - mConnectedWifiEntryPreferenceCategory.removeAll(); - mConnectedWifiEntryPreferenceCategory.setVisible(false); - } - - private void removeWifiEntryPreference() { - mWifiEntryPreferenceCategory.removeAll(); - mWifiEntryPreferenceCategory.setVisible(false); - } - - @VisibleForTesting - void setAdditionalSettingsSummaries() { - mConfigureWifiSettingsPreference.setSummary(getString( - isWifiWakeupEnabled() - ? R.string.wifi_configure_settings_preference_summary_wakeup_on - : R.string.wifi_configure_settings_preference_summary_wakeup_off)); - - final int numSavedNetworks = mWifiPickerTracker.getNumSavedNetworks(); - final int numSavedSubscriptions = mWifiPickerTracker.getNumSavedSubscriptions(); - if (numSavedNetworks + numSavedSubscriptions > 0) { - mSavedNetworksPreference.setVisible(true); - mSavedNetworksPreference.setSummary( - getSavedNetworkSettingsSummaryText(numSavedNetworks, numSavedSubscriptions)); - } else { - mSavedNetworksPreference.setVisible(false); - } - } - - private String getSavedNetworkSettingsSummaryText( - int numSavedNetworks, int numSavedSubscriptions) { - if (numSavedSubscriptions == 0) { - return getResources().getQuantityString(R.plurals.wifi_saved_access_points_summary, - numSavedNetworks, numSavedNetworks); - } else if (numSavedNetworks == 0) { - return getResources().getQuantityString( - R.plurals.wifi_saved_passpoint_access_points_summary, - numSavedSubscriptions, numSavedSubscriptions); - } else { - final int numTotalEntries = numSavedNetworks + numSavedSubscriptions; - return getResources().getQuantityString(R.plurals.wifi_saved_all_access_points_summary, - numTotalEntries, numTotalEntries); - } - } - - private boolean isWifiWakeupEnabled() { - final Context context = getContext(); - final PowerManager powerManager = context.getSystemService(PowerManager.class); - final ContentResolver contentResolver = context.getContentResolver(); - return mWifiManager.isAutoWakeupEnabled() - && mWifiManager.isScanAlwaysAvailable() - && Settings.Global.getInt(contentResolver, - Settings.Global.AIRPLANE_MODE_ON, 0) == 0 - && !powerManager.isPowerSaveMode(); - } - - private void setOffMessage() { - final CharSequence title = getText(R.string.wifi_empty_list_wifi_off); - // Don't use WifiManager.isScanAlwaysAvailable() to check the Wi-Fi scanning mode. Instead, - // read the system settings directly. Because when the device is in Airplane mode, even if - // Wi-Fi scanning mode is on, WifiManager.isScanAlwaysAvailable() still returns "off". - // TODO(b/149421497): Fix this? - final boolean wifiScanningMode = mWifiManager.isScanAlwaysAvailable(); - final CharSequence description = wifiScanningMode ? getText(R.string.wifi_scan_notify_text) - : getText(R.string.wifi_scan_notify_text_scanning_off); - final LinkifyUtils.OnClickListener clickListener = - () -> new SubSettingLauncher(getContext()) - .setDestination(ScanningSettings.class.getName()) - .setTitleRes(R.string.location_scanning_screen_title) - .setSourceMetricsCategory(getMetricsCategory()) - .launch(); - mStatusMessagePreference.setText(title, description, clickListener); - removeConnectedWifiEntryPreference(); - removeWifiEntryPreference(); - mStatusMessagePreference.setVisible(true); - } - - private void addMessagePreference(int messageId) { - mStatusMessagePreference.setTitle(messageId); - mStatusMessagePreference.setVisible(true); - - } - - protected void setProgressBarVisible(boolean visible) { - if (mProgressHeader != null) { - mProgressHeader.setVisibility(visible ? View.VISIBLE : View.GONE); - } - } - - @VisibleForTesting - void handleAddNetworkRequest(int result, Intent data) { - if (result == Activity.RESULT_OK) { - handleAddNetworkSubmitEvent(data); - } - } - - private void handleAddNetworkSubmitEvent(Intent data) { - final WifiConfiguration wifiConfiguration = data.getParcelableExtra( - AddNetworkFragment.WIFI_CONFIG_KEY); - if (wifiConfiguration != null) { - mWifiManager.save(wifiConfiguration, mSaveListener); - } - } - - /** - * Called when "add network" button is pressed. - */ - private void onAddNetworkPressed() { - launchAddNetworkFragment(); - } - - @Override - public int getHelpResource() { - return R.string.help_url_wifi; - } - - /** - * Renames/replaces "Next" button when appropriate. "Next" button usually exists in - * Wi-Fi setup screens, not in usual wifi settings screen. - * - * @param enabled true when the device is connected to a wifi network. - */ - @VisibleForTesting - void changeNextButtonState(boolean enabled) { - if (mEnableNextOnConnection && hasNextButton()) { - getNextButton().setEnabled(enabled); - } - } - - @Override - public void onForget(WifiDialog2 dialog) { - forget(dialog.getWifiEntry()); - } - - @Override - public void onSubmit(WifiDialog2 dialog) { - final int dialogMode = dialog.getMode(); - final WifiConfiguration config = dialog.getController().getConfig(); - final WifiEntry wifiEntry = dialog.getWifiEntry(); - - if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) { - if (config == null) { - Toast.makeText(getContext(), R.string.wifi_failed_save_message, - Toast.LENGTH_SHORT).show(); - } else { - mWifiManager.save(config, mSaveListener); - } - } else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT - || (dialogMode == WifiConfigUiBase2.MODE_VIEW && wifiEntry.canConnect())) { - if (config == null) { - connect(wifiEntry, false /* editIfNoConfig */, - false /* fullScreenEdit*/); - } else { - mWifiManager.connect(config, new WifiConnectActionListener()); - } - } - } - - @Override - public void onScan(WifiDialog2 dialog, String ssid) { - // Launch QR code scanner to join a network. - startActivityForResult(WifiDppUtils.getEnrolleeQrCodeScannerIntent(ssid), - REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER); - } - - private void forget(WifiEntry wifiEntry) { - mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_FORGET); - wifiEntry.forget(null /* callback */); - } - - @VisibleForTesting - void connect(WifiEntry wifiEntry, boolean editIfNoConfig, boolean fullScreenEdit) { - mMetricsFeatureProvider.action(getActivity(), SettingsEnums.ACTION_WIFI_CONNECT, - wifiEntry.isSaved()); - - // If it's an unsaved secure WifiEntry, it will callback - // ConnectCallback#onConnectResult with ConnectCallback#CONNECT_STATUS_FAILURE_NO_CONFIG - wifiEntry.connect(new WifiEntryConnectCallback(wifiEntry, editIfNoConfig, - fullScreenEdit)); - } - - private class WifiConnectActionListener implements WifiManager.ActionListener { - @Override - public void onSuccess() { - mClickedConnect = true; - } - - @Override - public void onFailure(int reason) { - if (isFinishingOrDestroyed()) { - return; - } - Toast.makeText(getContext(), R.string.wifi_failed_connect_message, Toast.LENGTH_SHORT) - .show(); - } - }; - - public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.wifi_settings2) { - @Override - public List getNonIndexableKeys(Context context) { - final List keys = super.getNonIndexableKeys(context); - - final WifiManager wifiManager = context.getSystemService(WifiManager.class); - if (WifiSavedConfigUtils.getAllConfigsCount(context, wifiManager) == 0) { - keys.add(PREF_KEY_SAVED_NETWORKS); - } - - if (!DataUsageUtils.hasWifiRadio(context)) { - keys.add(PREF_KEY_DATA_USAGE); - } - return keys; - } - }; - - private class WifiEntryConnectCallback implements ConnectCallback { - final WifiEntry mConnectWifiEntry; - final boolean mEditIfNoConfig; - final boolean mFullScreenEdit; - - WifiEntryConnectCallback(WifiEntry connectWifiEntry, boolean editIfNoConfig, - boolean fullScreenEdit) { - mConnectWifiEntry = connectWifiEntry; - mEditIfNoConfig = editIfNoConfig; - mFullScreenEdit = fullScreenEdit; - } - - @Override - public void onConnectResult(@ConnectStatus int status) { - if (isFinishingOrDestroyed()) { - return; - } - - if (status == ConnectCallback.CONNECT_STATUS_SUCCESS) { - mClickedConnect = true; - } else if (status == ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) { - if (mEditIfNoConfig) { - // Edit an unsaved secure Wi-Fi network. - if (mFullScreenEdit) { - launchConfigNewNetworkFragment(mConnectWifiEntry); - } else { - showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_CONNECT); - } - } - } else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) { - Toast.makeText(getContext(), R.string.wifi_failed_connect_message, - Toast.LENGTH_SHORT).show(); - } - } - } - - private void launchConfigNewNetworkFragment(WifiEntry wifiEntry) { - final Bundle bundle = new Bundle(); - bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY, - wifiEntry.getKey()); - new SubSettingLauncher(getContext()) - .setTitleText(wifiEntry.getTitle()) - .setDestination(ConfigureWifiEntryFragment.class.getName()) - .setArguments(bundle) - .setSourceMetricsCategory(getMetricsCategory()) - .setResultListener(WifiSettings2.this, CONFIG_NETWORK_REQUEST) - .launch(); - } - - /** Helper method to return whether a WifiEntry is disabled due to a wrong password */ - private static boolean isDisabledByWrongPassword(WifiEntry wifiEntry) { - WifiConfiguration config = wifiEntry.getWifiConfiguration(); - if (config == null) { - return false; - } - WifiConfiguration.NetworkSelectionStatus networkStatus = - config.getNetworkSelectionStatus(); - if (networkStatus == null - || networkStatus.getNetworkSelectionStatus() == NETWORK_SELECTION_ENABLED) { - return false; - } - int reason = networkStatus.getNetworkSelectionDisableReason(); - return WifiConfiguration.NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD == reason; - } - - @VisibleForTesting - void openSubscriptionHelpPage(WifiEntry wifiEntry) { - final Intent intent = getHelpIntent(getContext(), wifiEntry.getHelpUriString()); - if (intent != null) { - try { - startActivityForResult(intent, MANAGE_SUBSCRIPTION); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Activity was not found for intent, " + intent.toString()); - } - } - } - - @VisibleForTesting - Intent getHelpIntent(Context context, String helpUrlString) { - return HelpUtils.getHelpIntent(context, helpUrlString, context.getClass().getName()); - } -} diff --git a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java index 20f0716aa2e..181821b85bb 100644 --- a/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java +++ b/tests/robotests/src/com/android/settings/search/CustomSiteMapRegistryTest.java @@ -35,7 +35,7 @@ import com.android.settings.security.SecuritySettings; import com.android.settings.security.screenlock.ScreenLockSettings; import com.android.settings.system.SystemDashboardFragment; import com.android.settings.wallpaper.WallpaperSuggestionActivity; -import com.android.settings.wifi.WifiSettings2; +import com.android.settings.wifi.WifiSettings; import org.junit.Test; import org.junit.runner.RunWith; @@ -58,8 +58,8 @@ public class CustomSiteMapRegistryTest { } @Test - public void shouldContainWifiSettings2Pairs() { - assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(WifiSettings2.class.getName())) + public void shouldContainWifiSettingsPairs() { + assertThat(CustomSiteMapRegistry.CUSTOM_SITE_MAP.get(WifiSettings.class.getName())) .isEqualTo(NetworkDashboardFragment.class.getName()); } diff --git a/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java deleted file mode 100644 index 1189760c163..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/ConfigureAccessPointFragmentTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2019 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 static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import android.app.settings.SettingsEnums; -import android.os.Bundle; - -import com.android.settings.testutils.shadow.ShadowConnectivityManager; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.androidx.fragment.FragmentController; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = ShadowConnectivityManager.class) -public class ConfigureAccessPointFragmentTest { - - private static final String KEY_SSID = "key_ssid"; - private static final String KEY_SECURITY = "key_security"; - - private ConfigureAccessPointFragment mConfigureAccessPointFragment; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - Bundle bundle = new Bundle(); - - bundle.putString(KEY_SSID, "Test AP"); - bundle.putInt(KEY_SECURITY, 1 /* WEP */); - mConfigureAccessPointFragment = spy(new ConfigureAccessPointFragment()); - mConfigureAccessPointFragment.setArguments(bundle); - FragmentController.setupFragment(mConfigureAccessPointFragment); - } - - @Test - public void getMetricsCategory_shouldReturnConfigureNetwork() { - assertThat(mConfigureAccessPointFragment.getMetricsCategory()).isEqualTo( - SettingsEnums.SETTINGS_WIFI_CONFIGURE_NETWORK); - } - - @Test - public void getMode_shouldBeModeConnected() { - assertThat(mConfigureAccessPointFragment.getMode()).isEqualTo( - WifiConfigUiBase.MODE_CONNECT); - } - - @Test - public void launchFragment_shouldShowSubmitButton() { - assertThat(mConfigureAccessPointFragment.getSubmitButton()).isNotNull(); - } - - @Test - public void launchFragment_shouldShowCancelButton() { - assertThat(mConfigureAccessPointFragment.getCancelButton()).isNotNull(); - } - - @Test - public void onClickSubmitButton_shouldHandleSubmitAction() { - mConfigureAccessPointFragment.getSubmitButton().performClick(); - - verify(mConfigureAccessPointFragment).handleSubmitAction(); - } - - @Test - public void dispatchSubmit_shouldHandleSubmitAction() { - mConfigureAccessPointFragment.dispatchSubmit(); - - verify(mConfigureAccessPointFragment).handleSubmitAction(); - } - - @Test - public void onClickCancelButton_shouldHandleCancelAction() { - mConfigureAccessPointFragment.getCancelButton().performClick(); - - verify(mConfigureAccessPointFragment).handleCancelAction(); - } -} diff --git a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java b/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java deleted file mode 100644 index bb9971b6bed..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/ConnectedAccessPointPreferenceTest.java +++ /dev/null @@ -1,94 +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 static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.view.View; - -import com.android.settings.R; -import com.android.settingslib.wifi.AccessPoint; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; - -@RunWith(RobolectricTestRunner.class) -public class ConnectedAccessPointPreferenceTest { - - @Mock - private AccessPoint mAccessPoint; - @Mock - private View mView; - @Mock - private ConnectedAccessPointPreference.OnGearClickListener mOnGearClickListener; - private Context mContext; - private ConnectedAccessPointPreference mConnectedAccessPointPreference; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - - mContext = RuntimeEnvironment.application; - mConnectedAccessPointPreference = new ConnectedAccessPointPreference(mAccessPoint, mContext, - null, 0 /* iconResId */, false /* forSavedNetworks */, null /* fragment */); - mConnectedAccessPointPreference.setOnGearClickListener(mOnGearClickListener); - } - - @Test - public void testOnClick_gearClicked_listenerInvoked() { - when(mView.getId()).thenReturn(R.id.settings_button); - - mConnectedAccessPointPreference.onClick(mView); - - verify(mOnGearClickListener).onGearClick(mConnectedAccessPointPreference); - } - - @Test - public void testOnClick_gearNotClicked_listenerNotInvoked() { - mConnectedAccessPointPreference.onClick(mView); - - verify(mOnGearClickListener, never()).onGearClick(mConnectedAccessPointPreference); - } - - @Test - public void testCaptivePortalStatus_isCaptivePortal_dividerDrawn() { - mConnectedAccessPointPreference.setCaptivePortal(true); - assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isTrue(); - } - - @Test - public void testCaptivePortalStatus_isNotCaptivePortal_dividerNotDrawn() { - mConnectedAccessPointPreference.setCaptivePortal(false); - assertThat(mConnectedAccessPointPreference.shouldShowDivider()).isFalse(); - } - - @Test - public void testWidgetLayoutPreference() { - assertThat(mConnectedAccessPointPreference.getWidgetLayoutResource()) - .isEqualTo(R.layout.preference_widget_gear_optional_background); - } -} diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java b/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java deleted file mode 100644 index b2a28db8dce..00000000000 --- a/tests/robotests/src/com/android/settings/wifi/WifiSettings2Test.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2019 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 static com.android.settings.wifi.WifiConfigUiBase2.MODE_CONNECT; -import static com.android.settings.wifi.WifiConfigUiBase2.MODE_MODIFY; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.app.Activity; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; -import android.os.Bundle; -import android.os.PowerManager; -import android.os.UserManager; -import android.provider.Settings; -import android.view.ContextMenu; -import android.view.View; - -import androidx.fragment.app.FragmentActivity; -import androidx.preference.Preference; -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.settings.R; -import com.android.settings.datausage.DataUsagePreference; -import com.android.settings.testutils.shadow.ShadowDataUsageUtils; -import com.android.settings.testutils.shadow.ShadowFragment; -import com.android.settingslib.wifi.LongPressWifiEntryPreference; -import com.android.wifitrackerlib.WifiEntry; -import com.android.wifitrackerlib.WifiPickerTracker; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowToast; - -@RunWith(RobolectricTestRunner.class) -public class WifiSettings2Test { - - private static final int NUM_NETWORKS = 4; - private static final String FAKE_URI_STRING = "fakeuri"; - - @Mock - private PowerManager mPowerManager; - @Mock - private WifiManager mWifiManager; - @Mock - private DataUsagePreference mDataUsagePreference; - private Context mContext; - private WifiSettings2 mWifiSettings2; - @Mock - private WifiPickerTracker mMockWifiPickerTracker; - @Mock - private PreferenceManager mPreferenceManager; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - - mWifiSettings2 = spy(new WifiSettings2()); - doReturn(mContext).when(mWifiSettings2).getContext(); - doReturn(mPreferenceManager).when(mWifiSettings2).getPreferenceManager(); - doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); - doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); - doReturn(mContext).when(mPreferenceManager).getContext(); - mWifiSettings2.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext); - mWifiSettings2.mSavedNetworksPreference = new Preference(mContext); - mWifiSettings2.mConfigureWifiSettingsPreference = new Preference(mContext); - mWifiSettings2.mWifiPickerTracker = mMockWifiPickerTracker; - mWifiSettings2.mWifiManager = mWifiManager; - } - - @Test - public void addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent() { - final WifiSettings2 wifiSettings2 = spy(new WifiSettings2()); - final Intent intent = new Intent(); - doNothing().when(wifiSettings2).handleAddNetworkRequest(anyInt(), any(Intent.class)); - - wifiSettings2.onActivityResult(WifiSettings2.ADD_NETWORK_REQUEST, Activity.RESULT_OK, - intent); - - verify(wifiSettings2).handleAddNetworkRequest(anyInt(), any(Intent.class)); - } - - @Test - public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() { - when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS); - when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue(); - assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo( - mContext.getResources().getQuantityString( - R.plurals.wifi_saved_access_points_summary, - NUM_NETWORKS, NUM_NETWORKS)); - } - - @Test - public void setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible() { - when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */); - when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue(); - assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo( - mContext.getResources().getQuantityString( - R.plurals.wifi_saved_passpoint_access_points_summary, - NUM_NETWORKS, NUM_NETWORKS)); - } - - @Test - public void setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible() { - when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS); - when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isTrue(); - assertThat(mWifiSettings2.mSavedNetworksPreference.getSummary()).isEqualTo( - mContext.getResources().getQuantityString( - R.plurals.wifi_saved_all_access_points_summary, - NUM_NETWORKS*2, NUM_NETWORKS*2)); - } - - @Test - public void setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible() { - when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */); - when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mSavedNetworksPreference.isVisible()).isFalse(); - } - - @Test - public void setAdditionalSettingsSummaries_wifiWakeupEnabled_displayOn() { - final ContentResolver contentResolver = mContext.getContentResolver(); - when(mWifiManager.isAutoWakeupEnabled()).thenReturn(true); - when(mWifiManager.isScanAlwaysAvailable()).thenReturn(true); - Settings.Global.putInt(contentResolver, Settings.Global.AIRPLANE_MODE_ON, 0); - when(mPowerManager.isPowerSaveMode()).thenReturn(false); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mConfigureWifiSettingsPreference.getSummary()).isEqualTo( - mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_on)); - } - - @Test - public void setAdditionalSettingsSummaries_wifiWakeupDisabled_displayOff() { - final ContentResolver contentResolver = mContext.getContentResolver(); - when(mWifiManager.isAutoWakeupEnabled()).thenReturn(false); - - mWifiSettings2.setAdditionalSettingsSummaries(); - - assertThat(mWifiSettings2.mConfigureWifiSettingsPreference.getSummary()).isEqualTo( - mContext.getString(R.string.wifi_configure_settings_preference_summary_wakeup_off)); - } - - @Test - public void checkAddWifiNetworkPrefernce_preferenceVisible() { - assertThat(mWifiSettings2.mAddWifiNetworkPreference.isVisible()).isTrue(); - assertThat(mWifiSettings2.mAddWifiNetworkPreference.getTitle()).isEqualTo( - mContext.getString(R.string.wifi_add_network)); - } - - private void setUpForOnCreate() { - final FragmentActivity activity = mock(FragmentActivity.class); - when(mWifiSettings2.getActivity()).thenReturn(activity); - final Resources.Theme theme = mContext.getTheme(); - when(activity.getTheme()).thenReturn(theme); - UserManager userManager = mock(UserManager.class); - when(activity.getSystemService(Context.USER_SERVICE)) - .thenReturn(userManager); - - when(mWifiSettings2.findPreference(WifiSettings2.PREF_KEY_DATA_USAGE)) - .thenReturn(mDataUsagePreference); - } - - @Test - @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) - public void checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported() { - setUpForOnCreate(); - ShadowDataUsageUtils.IS_WIFI_SUPPORTED = false; - - mWifiSettings2.onCreate(Bundle.EMPTY); - - verify(mDataUsagePreference).setVisible(false); - } - - @Test - @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) - public void checkDataUsagePreference_perferenceVisibleIfWifiSupported() { - setUpForOnCreate(); - ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; - - mWifiSettings2.onCreate(Bundle.EMPTY); - - verify(mDataUsagePreference).setVisible(true); - verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/, eq(null) /*service*/); - } - - @Test - public void onCreateAdapter_hasStableIdsTrue() { - final PreferenceScreen preferenceScreen = mock(PreferenceScreen.class); - when(preferenceScreen.getContext()).thenReturn(mContext); - - RecyclerView.Adapter adapter = mWifiSettings2.onCreateAdapter(preferenceScreen); - - assertThat(adapter.hasStableIds()).isTrue(); - } - - @Test - public void onCreateContextMenu_shouldHaveForgetAndDisconnectMenuForConnectedWifiEntry() { - final FragmentActivity activity = mock(FragmentActivity.class); - when(activity.getApplicationContext()).thenReturn(mContext); - when(mWifiSettings2.getActivity()).thenReturn(activity); - - final WifiEntry wifiEntry = mock(WifiEntry.class); - when(wifiEntry.canDisconnect()).thenReturn(true); - when(wifiEntry.canForget()).thenReturn(true); - when(wifiEntry.isSaved()).thenReturn(true); - when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED); - - final LongPressWifiEntryPreference connectedWifiEntryPreference = - mWifiSettings2.createLongPressWifiEntryPreference(wifiEntry); - final View view = mock(View.class); - when(view.getTag()).thenReturn(connectedWifiEntryPreference); - - final ContextMenu menu = mock(ContextMenu.class); - mWifiSettings2.onCreateContextMenu(menu, view, null /* info */); - - verify(menu).add(anyInt(), eq(WifiSettings2.MENU_ID_FORGET), anyInt(), anyInt()); - verify(menu).add(anyInt(), eq(WifiSettings2.MENU_ID_DISCONNECT), anyInt(), anyInt()); - } - - @Test - public void onWifiEntriesChanged_shouldChangeNextButtonState() { - mWifiSettings2.onWifiEntriesChanged(); - - verify(mWifiSettings2).changeNextButtonState(anyBoolean()); - } - - @Test - public void openSubscriptionHelpPage_shouldCallStartActivityForResult() { - doReturn(new Intent()).when(mWifiSettings2).getHelpIntent(mContext, FAKE_URI_STRING); - doNothing().when(mWifiSettings2).startActivityForResult(any(Intent.class), anyInt()); - final WifiEntry mockWifiEntry = mock(WifiEntry.class); - when(mockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING); - - mWifiSettings2.openSubscriptionHelpPage(mockWifiEntry); - - verify(mWifiSettings2, times(1)).startActivityForResult(any(), anyInt()); - } - - @Test - public void onNumSavedNetworksChanged_isFinishing_ShouldNotCrash() { - final FragmentActivity activity = mock(FragmentActivity.class); - when(activity.isFinishing()).thenReturn(true); - when(mWifiSettings2.getActivity()).thenReturn(activity); - when(mWifiSettings2.getContext()).thenReturn(null); - - mWifiSettings2.onNumSavedNetworksChanged(); - } - - @Test - public void onNumSavedSubscriptionsChanged_isFinishing_ShouldNotCrash() { - final FragmentActivity activity = mock(FragmentActivity.class); - when(activity.isFinishing()).thenReturn(true); - when(mWifiSettings2.getActivity()).thenReturn(activity); - when(mWifiSettings2.getContext()).thenReturn(null); - - mWifiSettings2.onNumSavedSubscriptionsChanged(); - } - - @Test - public void onSubmit_modeModifyNoConfig_toastErrorMessage() { - WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, null /* config */); - - mWifiSettings2.onSubmit(dialog); - - assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo( - mContext.getString(R.string.wifi_failed_save_message)); - } - - @Test - public void onSubmit_modeModifyHasConfig_saveWifiManager() { - final WifiConfiguration config = mock(WifiConfiguration.class); - WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, config); - - mWifiSettings2.onSubmit(dialog); - - verify(mWifiManager).save(eq(config), any()); - } - - @Test - public void onSubmit_modeConnectNoConfig_connectWifiEntry() { - WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, null /* config */); - final WifiEntry wifiEntry = dialog.getWifiEntry(); - - mWifiSettings2.onAttach(mContext); - mWifiSettings2.onSubmit(dialog); - - verify(mWifiSettings2).connect(wifiEntry, false /* editIfNoConfig */, - false /* fullScreenEdit*/); - } - - @Test - public void onSubmit_modeConnectHasConfig_connectWifiManager() { - final WifiConfiguration config = mock(WifiConfiguration.class); - WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, config); - - mWifiSettings2.onSubmit(dialog); - - verify(mWifiManager).connect(eq(config), any(WifiManager.ActionListener.class)); - } - - private WifiDialog2 createWifiDialog2(int mode, WifiConfiguration config) { - final WifiEntry wifiEntry = mock(WifiEntry.class); - when(wifiEntry.canConnect()).thenReturn(true); - final WifiConfigController2 controller = mock(WifiConfigController2.class); - when(controller.getConfig()).thenReturn(config); - final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */, - wifiEntry, mode)); - when(wifiDialog2.getController()).thenReturn(controller); - return wifiDialog2; - } -} diff --git a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java index b955156851d..7eba586720c 100644 --- a/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java +++ b/tests/robotests/src/com/android/settings/wifi/WifiSettingsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 The Android Open Source Project + * Copyright (C) 2019 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. @@ -15,17 +15,20 @@ */ package com.android.settings.wifi; -import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED; +import static com.android.settings.wifi.WifiConfigUiBase2.MODE_CONNECT; +import static com.android.settings.wifi.WifiConfigUiBase2.MODE_MODIFY; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -33,91 +36,58 @@ import android.app.Activity; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.content.res.Resources; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.wifi.EAPConstants; import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; -import android.net.wifi.hotspot2.PasspointConfiguration; -import android.net.wifi.hotspot2.pps.Credential; -import android.net.wifi.hotspot2.pps.HomeSp; import android.os.Bundle; import android.os.PowerManager; import android.os.UserManager; import android.provider.Settings; -import android.util.FeatureFlagUtils; import android.view.ContextMenu; import android.view.View; import androidx.fragment.app.FragmentActivity; import androidx.preference.Preference; +import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; -import com.android.settings.SettingsActivity; import com.android.settings.datausage.DataUsagePreference; -import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowDataUsageUtils; import com.android.settings.testutils.shadow.ShadowFragment; -import com.android.settings.widget.SwitchBar; -import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; -import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.WifiTracker; -import com.android.settingslib.wifi.WifiTrackerFactory; +import com.android.settingslib.wifi.LongPressWifiEntryPreference; +import com.android.wifitrackerlib.WifiEntry; +import com.android.wifitrackerlib.WifiPickerTracker; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import org.robolectric.util.ReflectionHelpers; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import org.robolectric.shadows.ShadowToast; @RunWith(RobolectricTestRunner.class) public class WifiSettingsTest { private static final int NUM_NETWORKS = 4; + private static final String FAKE_URI_STRING = "fakeuri"; - @Mock - private WifiTracker mWifiTracker; @Mock private PowerManager mPowerManager; @Mock - private DataUsagePreference mDataUsagePreference; - @Mock - private RecyclerView mRecyclerView; - @Mock - private RecyclerView.Adapter mRecyclerViewAdapter; - @Mock - private View mHeaderView; - @Mock private WifiManager mWifiManager; @Mock - private ConnectivityManager mConnectivityManager; - @Mock - private Intent mActivityIntent; - @Mock - private SwitchBar mSwitchBar; - @Mock - private WifiInfo mWifiInfo; - @Mock - private PackageManager mPackageManager; + private DataUsagePreference mDataUsagePreference; private Context mContext; private WifiSettings mWifiSettings; - private FakeFeatureFactory mFakeFeatureFactory; - private MetricsFeatureProvider mMetricsFeatureProvider; + @Mock + private WifiPickerTracker mMockWifiPickerTracker; + @Mock + private PreferenceManager mPreferenceManager; @Before public void setUp() { @@ -126,75 +96,33 @@ public class WifiSettingsTest { mWifiSettings = spy(new WifiSettings()); doReturn(mContext).when(mWifiSettings).getContext(); - doReturn(mRecyclerViewAdapter).when(mRecyclerView).getAdapter(); - doReturn(mRecyclerView).when(mWifiSettings).getListView(); + doReturn(mPreferenceManager).when(mWifiSettings).getPreferenceManager(); doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class); - doReturn(mHeaderView).when(mWifiSettings).setPinnedHeaderView(anyInt()); - doReturn(mWifiInfo).when(mWifiManager).getConnectionInfo(); - doReturn(mWifiManager).when(mWifiTracker).getManager(); + doReturn(mWifiManager).when(mContext).getSystemService(WifiManager.class); + doReturn(mContext).when(mPreferenceManager).getContext(); mWifiSettings.mAddWifiNetworkPreference = new AddWifiNetworkPreference(mContext); mWifiSettings.mSavedNetworksPreference = new Preference(mContext); mWifiSettings.mConfigureWifiSettingsPreference = new Preference(mContext); - mWifiSettings.mWifiTracker = mWifiTracker; + mWifiSettings.mWifiPickerTracker = mMockWifiPickerTracker; mWifiSettings.mWifiManager = mWifiManager; - mWifiSettings.mConnectivityManager = mConnectivityManager; - mFakeFeatureFactory = FakeFeatureFactory.setupForTest(); - mMetricsFeatureProvider = mFakeFeatureFactory.getMetricsFeatureProvider(); - ReflectionHelpers.setField(mWifiSettings, "mMetricsFeatureProvider", - mMetricsFeatureProvider); - WifiTrackerFactory.setTestingWifiTracker(mWifiTracker); } @Test public void addNetworkFragmentSendResult_onActivityResult_shouldHandleEvent() { - final WifiSettings wifiSettings = spy(new WifiSettings()); + final WifiSettings WifiSettings = spy(new WifiSettings()); final Intent intent = new Intent(); - doNothing().when(wifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); + doNothing().when(WifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); - wifiSettings.onActivityResult(WifiSettings.ADD_NETWORK_REQUEST, Activity.RESULT_OK, intent); + WifiSettings.onActivityResult(WifiSettings.ADD_NETWORK_REQUEST, Activity.RESULT_OK, + intent); - verify(wifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); - } - - private List createMockWifiConfigurations(int count) { - final List mockConfigs = new ArrayList<>(); - for (int i = 0; i < count; i++) { - mockConfigs.add(new WifiConfiguration()); - } - return mockConfigs; - } - - private List createMockPasspointConfigurations(int count) { - final List mockConfigs = new ArrayList<>(); - for (int i = 0; i < count; i++) { - final HomeSp sp = new HomeSp(); - sp.setFqdn("fqdn"); - final PasspointConfiguration config = new PasspointConfiguration(); - config.setHomeSp(sp); - Credential.SimCredential simCredential = new Credential.SimCredential(); - Credential credential = new Credential(); - credential.setRealm("test.example.com"); - simCredential.setImsi("12345*"); - simCredential.setEapType(EAPConstants.EAP_SIM); - credential.setSimCredential(simCredential); - config.setCredential(credential); - mockConfigs.add(config); - } - return mockConfigs; - } - - static NetworkCapabilities makeCaptivePortalNetworkCapabilities() { - final NetworkCapabilities capabilities = new NetworkCapabilities(); - capabilities.clearAll(); - capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); - capabilities.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL); - return capabilities; + verify(WifiSettings).handleAddNetworkRequest(anyInt(), any(Intent.class)); } @Test public void setAdditionalSettingsSummaries_hasSavedNetwork_preferenceVisible() { - when(mWifiManager.getConfiguredNetworks()) - .thenReturn(createMockWifiConfigurations(NUM_NETWORKS)); + when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS); + when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */); mWifiSettings.setAdditionalSettingsSummaries(); @@ -207,8 +135,8 @@ public class WifiSettingsTest { @Test public void setAdditionalSettingsSummaries_hasSavedPasspointNetwork_preferenceVisible() { - when(mWifiManager.getPasspointConfigurations()) - .thenReturn(createMockPasspointConfigurations(NUM_NETWORKS)); + when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */); + when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS); mWifiSettings.setAdditionalSettingsSummaries(); @@ -221,10 +149,8 @@ public class WifiSettingsTest { @Test public void setAdditionalSettingsSummaries_hasTwoKindsSavedNetwork_preferenceVisible() { - when(mWifiManager.getConfiguredNetworks()) - .thenReturn(createMockWifiConfigurations(NUM_NETWORKS)); - when(mWifiManager.getPasspointConfigurations()) - .thenReturn(createMockPasspointConfigurations(NUM_NETWORKS)); + when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(NUM_NETWORKS); + when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(NUM_NETWORKS); mWifiSettings.setAdditionalSettingsSummaries(); @@ -237,8 +163,8 @@ public class WifiSettingsTest { @Test public void setAdditionalSettingsSummaries_noSavedNetwork_preferenceInvisible() { - when(mWifiManager.getConfiguredNetworks()) - .thenReturn(createMockWifiConfigurations(0 /* count */)); + when(mMockWifiPickerTracker.getNumSavedNetworks()).thenReturn(0 /* count */); + when(mMockWifiPickerTracker.getNumSavedSubscriptions()).thenReturn(0 /* count */); mWifiSettings.setAdditionalSettingsSummaries(); @@ -278,29 +204,21 @@ public class WifiSettingsTest { } private void setUpForOnCreate() { - final SettingsActivity activity = mock(SettingsActivity.class); - when(activity.getSwitchBar()).thenReturn(mSwitchBar); + final FragmentActivity activity = mock(FragmentActivity.class); when(mWifiSettings.getActivity()).thenReturn(activity); final Resources.Theme theme = mContext.getTheme(); when(activity.getTheme()).thenReturn(theme); - when(activity.getIntent()).thenReturn(mActivityIntent); UserManager userManager = mock(UserManager.class); when(activity.getSystemService(Context.USER_SERVICE)) .thenReturn(userManager); + when(mWifiSettings.findPreference(WifiSettings.PREF_KEY_DATA_USAGE)) .thenReturn(mDataUsagePreference); - when(activity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); - when(activity.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); - when(activity.getPackageManager()).thenReturn(mPackageManager); } @Test @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) public void checkDataUsagePreference_perferenceInvisibleIfWifiNotSupported() { - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - return; - } - setUpForOnCreate(); ShadowDataUsageUtils.IS_WIFI_SUPPORTED = false; @@ -312,10 +230,6 @@ public class WifiSettingsTest { @Test @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) public void checkDataUsagePreference_perferenceVisibleIfWifiSupported() { - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - return; - } - setUpForOnCreate(); ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; @@ -325,28 +239,6 @@ public class WifiSettingsTest { verify(mDataUsagePreference).setTemplate(any(), eq(0) /*subId*/, eq(null) /*service*/); } - @Test - public void onCreateContextMenu_shouldHaveForgetMenuForConnectedAccessPreference() { - final FragmentActivity mockActivity = mock(FragmentActivity.class); - when(mockActivity.getApplicationContext()).thenReturn(mContext); - when(mWifiSettings.getActivity()).thenReturn(mockActivity); - - final AccessPoint accessPoint = mock(AccessPoint.class); - when(accessPoint.isConnectable()).thenReturn(false); - when(accessPoint.isSaved()).thenReturn(true); - when(accessPoint.isActive()).thenReturn(true); - - final ConnectedAccessPointPreference connectedPreference = - mWifiSettings.createConnectedAccessPointPreference(accessPoint, mContext); - final View view = mock(View.class); - when(view.getTag()).thenReturn(connectedPreference); - - final ContextMenu menu = mock(ContextMenu.class); - mWifiSettings.onCreateContextMenu(menu, view, null /* info */); - - verify(menu).add(anyInt(), eq(WifiSettings.MENU_ID_FORGET), anyInt(), anyInt()); - } - @Test public void onCreateAdapter_hasStableIdsTrue() { final PreferenceScreen preferenceScreen = mock(PreferenceScreen.class); @@ -358,60 +250,118 @@ public class WifiSettingsTest { } @Test - @Config(shadows = {ShadowDataUsageUtils.class, ShadowFragment.class}) - public void clickOnWifiNetworkWith_shouldStartCaptivePortalApp() { - if (FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_WIFITRACKER2)) { - return; - } + public void onCreateContextMenu_shouldHaveForgetAndDisconnectMenuForConnectedWifiEntry() { + final FragmentActivity activity = mock(FragmentActivity.class); + when(activity.getApplicationContext()).thenReturn(mContext); + when(mWifiSettings.getActivity()).thenReturn(activity); - when(mWifiManager.getConfiguredNetworks()).thenReturn(createMockWifiConfigurations( - NUM_NETWORKS)); - when(mWifiTracker.isConnected()).thenReturn(true); + final WifiEntry wifiEntry = mock(WifiEntry.class); + when(wifiEntry.canDisconnect()).thenReturn(true); + when(wifiEntry.canForget()).thenReturn(true); + when(wifiEntry.isSaved()).thenReturn(true); + when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED); - final AccessPoint accessPointActive = mock(AccessPoint.class); - when(accessPointActive.isActive()).thenReturn(true); - when(accessPointActive.isSaved()).thenReturn(false); - when(accessPointActive.getConfig()).thenReturn(mock(WifiConfiguration.class)); + final LongPressWifiEntryPreference connectedWifiEntryPreference = + mWifiSettings.createLongPressWifiEntryPreference(wifiEntry); + final View view = mock(View.class); + when(view.getTag()).thenReturn(connectedWifiEntryPreference); - final AccessPoint accessPointInactive = mock(AccessPoint.class); - when(accessPointInactive.isActive()).thenReturn(false); - when(accessPointInactive.isSaved()).thenReturn(false); - when(accessPointInactive.getConfig()).thenReturn(mock(WifiConfiguration.class)); + final ContextMenu menu = mock(ContextMenu.class); + mWifiSettings.onCreateContextMenu(menu, view, null /* info */); - when(mWifiTracker.getAccessPoints()).thenReturn(Arrays.asList(accessPointActive, - accessPointInactive)); - when(mWifiManager.getWifiState()).thenReturn(WIFI_STATE_ENABLED); - when(mWifiManager.isWifiEnabled()).thenReturn(true); + verify(menu).add(anyInt(), eq(WifiSettings.MENU_ID_FORGET), anyInt(), anyInt()); + verify(menu).add(anyInt(), eq(WifiSettings.MENU_ID_DISCONNECT), anyInt(), anyInt()); + } - final Network network = mock(Network.class); - when(mWifiManager.getCurrentNetwork()).thenReturn(network); + @Test + public void onWifiEntriesChanged_shouldChangeNextButtonState() { + mWifiSettings.onWifiEntriesChanged(); - // Simulate activity creation cycle - setUpForOnCreate(); - ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; - mWifiSettings.onCreate(Bundle.EMPTY); - mWifiSettings.onActivityCreated(null); - mWifiSettings.onViewCreated(new View(mContext), new Bundle()); - mWifiSettings.onStart(); + verify(mWifiSettings).changeNextButtonState(anyBoolean()); + } - // Click on open network - final Preference openWifiPref = new LongPressAccessPointPreference(accessPointInactive, - mContext, null, - false /* forSavedNetworks */, R.drawable.ic_wifi_signal_0, - null); - mWifiSettings.onPreferenceTreeClick(openWifiPref); + @Test + public void openSubscriptionHelpPage_shouldCallStartActivityForResult() { + doReturn(new Intent()).when(mWifiSettings).getHelpIntent(mContext, FAKE_URI_STRING); + doNothing().when(mWifiSettings).startActivityForResult(any(Intent.class), anyInt()); + final WifiEntry mockWifiEntry = mock(WifiEntry.class); + when(mockWifiEntry.getHelpUriString()).thenReturn(FAKE_URI_STRING); - // Ensure connect() was called, and fake success. - ArgumentCaptor wifiCallbackCaptor = ArgumentCaptor.forClass( - WifiManager.ActionListener.class); - verify(mWifiManager).connect(any(WifiConfiguration.class), wifiCallbackCaptor.capture()); - wifiCallbackCaptor.getValue().onSuccess(); + mWifiSettings.openSubscriptionHelpPage(mockWifiEntry); - // Simulate capability change - mWifiSettings.mCaptivePortalNetworkCallback.onCapabilitiesChanged(network, - makeCaptivePortalNetworkCapabilities()); + verify(mWifiSettings, times(1)).startActivityForResult(any(), anyInt()); + } - // Ensure CP was called - verify(mConnectivityManager).startCaptivePortalApp(eq(network)); + @Test + public void onNumSavedNetworksChanged_isFinishing_ShouldNotCrash() { + final FragmentActivity activity = mock(FragmentActivity.class); + when(activity.isFinishing()).thenReturn(true); + when(mWifiSettings.getActivity()).thenReturn(activity); + when(mWifiSettings.getContext()).thenReturn(null); + + mWifiSettings.onNumSavedNetworksChanged(); + } + + @Test + public void onNumSavedSubscriptionsChanged_isFinishing_ShouldNotCrash() { + final FragmentActivity activity = mock(FragmentActivity.class); + when(activity.isFinishing()).thenReturn(true); + when(mWifiSettings.getActivity()).thenReturn(activity); + when(mWifiSettings.getContext()).thenReturn(null); + + mWifiSettings.onNumSavedSubscriptionsChanged(); + } + + @Test + public void onSubmit_modeModifyNoConfig_toastErrorMessage() { + WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, null /* config */); + + mWifiSettings.onSubmit(dialog); + + assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo( + mContext.getString(R.string.wifi_failed_save_message)); + } + + @Test + public void onSubmit_modeModifyHasConfig_saveWifiManager() { + final WifiConfiguration config = mock(WifiConfiguration.class); + WifiDialog2 dialog = createWifiDialog2(MODE_MODIFY, config); + + mWifiSettings.onSubmit(dialog); + + verify(mWifiManager).save(eq(config), any()); + } + + @Test + public void onSubmit_modeConnectNoConfig_connectWifiEntry() { + WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, null /* config */); + final WifiEntry wifiEntry = dialog.getWifiEntry(); + + mWifiSettings.onAttach(mContext); + mWifiSettings.onSubmit(dialog); + + verify(mWifiSettings).connect(wifiEntry, false /* editIfNoConfig */, + false /* fullScreenEdit*/); + } + + @Test + public void onSubmit_modeConnectHasConfig_connectWifiManager() { + final WifiConfiguration config = mock(WifiConfiguration.class); + WifiDialog2 dialog = createWifiDialog2(MODE_CONNECT, config); + + mWifiSettings.onSubmit(dialog); + + verify(mWifiManager).connect(eq(config), any(WifiManager.ActionListener.class)); + } + + private WifiDialog2 createWifiDialog2(int mode, WifiConfiguration config) { + final WifiEntry wifiEntry = mock(WifiEntry.class); + when(wifiEntry.canConnect()).thenReturn(true); + final WifiConfigController2 controller = mock(WifiConfigController2.class); + when(controller.getConfig()).thenReturn(config); + final WifiDialog2 wifiDialog2 = spy(WifiDialog2.createModal(mContext, null /* listener */, + wifiEntry, mode)); + when(wifiDialog2.getController()).thenReturn(controller); + return wifiDialog2; } } diff --git a/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java b/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java index bc8a52a148b..4c9b3c50fd1 100644 --- a/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java +++ b/tests/unit/src/com/android/settings/wifi/WifiSettingsUiTest.java @@ -15,31 +15,27 @@ */ package com.android.settings.wifi; +import static androidx.test.InstrumentationRegistry.getInstrumentation; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.matcher.ViewMatchers.Visibility.VISIBLE; import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; -import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static com.google.common.truth.Truth.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.startsWith; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; import android.content.Intent; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiConfiguration.NetworkSelectionStatus; -import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.provider.Settings; +import android.support.test.uiautomator.UiDevice; import androidx.fragment.app.Fragment; import androidx.test.InstrumentationRegistry; @@ -48,11 +44,8 @@ import androidx.test.runner.AndroidJUnit4; import com.android.settings.Settings.WifiSettingsActivity; import com.android.settingslib.utils.ThreadUtils; -import com.android.settingslib.wifi.AccessPoint; -import com.android.settingslib.wifi.TestAccessPointBuilder; -import com.android.settingslib.wifi.WifiTracker; -import com.android.settingslib.wifi.WifiTracker.WifiListener; -import com.android.settingslib.wifi.WifiTrackerFactory; +import com.android.wifitrackerlib.WifiEntry; +import com.android.wifitrackerlib.WifiPickerTracker; import com.google.common.collect.Lists; @@ -63,36 +56,28 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.nio.charset.StandardCharsets; import java.util.List; @RunWith(AndroidJUnit4.class) public class WifiSettingsUiTest { - private static final String TEST_SSID = "\"Test Ssid\""; - private static final String TEST_UNQUOTED_SSID = "Test Ssid"; - private static final String TEST_BSSID = "0a:08:5c:67:89:00"; - private static final int TEST_RSSI = 123; - private static final int TEST_NETWORK_ID = 1; + private static final String TEST_SSID = "Test Ssid"; + private static final String TEST_KEY = "Test Key"; // Keys used to lookup resources by name (see the resourceId/resourceString helper methods). - private static final String ID = "id"; private static final String STRING = "string"; private static final String WIFI_CONFIGURE_SETTINGS_PREFERENCE_TITLE = "wifi_configure_settings_preference_title"; private static final String WIFI_SAVED_ACCESS_POINTS_LABEL = "wifi_saved_access_points_label"; private static final String WIFI_EMPTY_LIST_WIFI_OFF = "wifi_empty_list_wifi_off"; private static final String WIFI_DISPLAY_STATUS_CONNECTED = "wifi_display_status_connected"; - private static final String WIFI_PASSWORD = "wifi_password"; - private static final String WIFI_SHOW_PASSWORD = "wifi_show_password"; - private static final String PASSWORD_LAYOUT = "password_layout"; - private static final String PASSWORD = "password"; @Mock - private WifiTracker mWifiTracker; + private WifiPickerTracker mWifiTracker; @Mock - private WifiManager mWifiManager; + private WifiPickerTracker.WifiPickerTrackerCallback mWifiListener; + private Context mContext; - private WifiListener mWifiListener; + private UiDevice mDevice; @Rule public ActivityTestRule mActivityRule = @@ -102,8 +87,7 @@ public class WifiSettingsUiTest { public void setUp() { MockitoAnnotations.initMocks(this); mContext = InstrumentationRegistry.getTargetContext(); - WifiTrackerFactory.setTestingWifiTracker(mWifiTracker); - when(mWifiTracker.getManager()).thenReturn(mWifiManager); + mDevice = UiDevice.getInstance(getInstrumentation()); } /** @@ -121,33 +105,6 @@ public class WifiSettingsUiTest { return mContext.getResources().getString(resourceId(STRING, name)); } - private void setupConnectedAccessPoint() { - WifiConfiguration config = new WifiConfiguration(); - config.SSID = TEST_SSID; - config.BSSID = TEST_BSSID; - config.networkId = TEST_NETWORK_ID; - WifiInfo wifiInfo = new WifiInfo.Builder() - .setSsid(TEST_UNQUOTED_SSID.getBytes(StandardCharsets.UTF_8)) - .setBssid(TEST_BSSID) - .setRssi(TEST_RSSI) - .setNetworkId(TEST_NETWORK_ID) - .build(); - NetworkInfo networkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, null, null); - networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null); - AccessPoint accessPoint = new AccessPoint(mContext, config); - accessPoint.update(config, wifiInfo, networkInfo); - - assertThat(accessPoint.getSsidStr()).isEqualTo(TEST_UNQUOTED_SSID); - assertThat(accessPoint.getBssid()).isEqualTo(TEST_BSSID); - assertThat(accessPoint.getNetworkInfo()).isNotNull(); - assertThat(accessPoint.isActive()).isTrue(); - assertThat(accessPoint.getSettingsSummary()).isEqualTo( - resourceString(WIFI_DISPLAY_STATUS_CONNECTED)); - - when(mWifiTracker.getAccessPoints()).thenReturn( - Lists.asList(accessPoint, new AccessPoint[] {})); - } - /** Launch the activity via an Intent with a String extra. */ private void launchActivity(String extraName, String extraValue) { Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS); @@ -156,11 +113,10 @@ public class WifiSettingsUiTest { } mActivityRule.launchActivity(intent); - verify(mWifiTracker).getManager(); - List fragments = mActivityRule.getActivity().getSupportFragmentManager().getFragments(); assertThat(fragments.size()).isEqualTo(1); + ((WifiSettings) fragments.get(0)).mWifiPickerTracker = mWifiTracker; mWifiListener = (WifiSettings) fragments.get(0); assertThat(mWifiListener).isNotNull(); } @@ -171,13 +127,7 @@ public class WifiSettingsUiTest { } private void setWifiState(int wifiState) { - when(mWifiManager.getWifiState()).thenReturn(wifiState); - when(mWifiManager.isWifiEnabled()).thenReturn(wifiState == WifiManager.WIFI_STATE_ENABLED); - } - - private void callOnWifiStateChanged(int state) { - mActivityRule.getActivity().getMainThreadHandler() - .post(() -> mWifiListener.onWifiStateChanged(state)); + when(mWifiTracker.getWifiState()).thenReturn(wifiState); } @Test @@ -210,28 +160,32 @@ public class WifiSettingsUiTest { when(mWifiTracker.getNumSavedNetworks()).thenReturn(1); launchActivity(); + mActivityRule.getActivity().getMainThreadHandler() + .post(() -> mWifiListener.onNumSavedNetworksChanged()); onView(allOf(withText(resourceId(STRING, WIFI_SAVED_ACCESS_POINTS_LABEL)), withEffectiveVisibility(VISIBLE))).check(matches(isDisplayed())); } @Test - public void onDisableWifi_seeOffMessage() { + public void onWifiStateChanged_wifiDisabled_seeOffMessage() { setWifiState(WifiManager.WIFI_STATE_DISABLED); launchActivity(); - callOnWifiStateChanged(WifiManager.WIFI_STATE_DISABLED); + mActivityRule.getActivity().getMainThreadHandler() + .post(() -> mWifiListener.onWifiStateChanged()); onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check( matches(isDisplayed())); } @Test - public void onEnableWifi_shouldNotSeeOffMessage() { + public void onWifiStateChanged_wifiEnabled_shouldNotSeeOffMessage() { setWifiState(WifiManager.WIFI_STATE_ENABLED); launchActivity(); - callOnWifiStateChanged(WifiManager.WIFI_STATE_ENABLED); + mActivityRule.getActivity().getMainThreadHandler() + .post(() -> mWifiListener.onWifiStateChanged()); onView(withText(startsWith(resourceString(WIFI_EMPTY_LIST_WIFI_OFF)))).check( doesNotExist()); @@ -240,94 +194,55 @@ public class WifiSettingsUiTest { @Test public void onConnected_shouldSeeConnectedMessage() { setWifiState(WifiManager.WIFI_STATE_ENABLED); - setupConnectedAccessPoint(); - when(mWifiTracker.isConnected()).thenReturn(true); + final WifiEntry wifiEntry = mock(WifiEntry.class); + when(wifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED); + when(wifiEntry.getSummary(false /* concise */)) + .thenReturn(resourceString(WIFI_DISPLAY_STATUS_CONNECTED)); + when(wifiEntry.getKey()).thenReturn(TEST_KEY); + when(mWifiTracker.getConnectedWifiEntry()).thenReturn(wifiEntry); launchActivity(); + ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged()); + mDevice.waitForIdle(); onView(withText(resourceString(WIFI_DISPLAY_STATUS_CONNECTED))).check( matches(isDisplayed())); } @Test - public void changingSecurityStateOnApShouldNotCauseMultipleListItems() { + public void changingSecurityStateOnAp_ShouldNotCauseMultipleListItems() { setWifiState(WifiManager.WIFI_STATE_ENABLED); - TestAccessPointBuilder builder = new TestAccessPointBuilder(mContext) - .setSsid(TEST_SSID) - .setSecurity(AccessPoint.SECURITY_NONE) - .setRssi(TEST_RSSI); - AccessPoint open = builder.build(); - builder.setSecurity(AccessPoint.SECURITY_EAP); - AccessPoint eap = builder.build(); + final WifiEntry openWifiEntry = mock(WifiEntry.class); + when(openWifiEntry.getTitle()).thenReturn(TEST_SSID); + when(openWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_NONE); - builder.setSecurity(AccessPoint.SECURITY_WEP); - AccessPoint wep = builder.build(); + final WifiEntry eapWifiEntry = mock(WifiEntry.class); + when(eapWifiEntry.getTitle()).thenReturn(TEST_SSID); + when(eapWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_EAP); - // Return a different security state each time getAccessPoints is invoked - when(mWifiTracker.getAccessPoints()) - .thenReturn(Lists.newArrayList(open)) - .thenReturn(Lists.newArrayList(eap)) - .thenReturn(Lists.newArrayList(wep)); + final WifiEntry wepWifiEntry = mock(WifiEntry.class); + when(wepWifiEntry.getTitle()).thenReturn(TEST_SSID); + when(wepWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_WEP); + + // Return a different security state each time getWifiEntries is invoked + when(mWifiTracker.getWifiEntries()) + .thenReturn(Lists.newArrayList(openWifiEntry)) + .thenReturn(Lists.newArrayList(eapWifiEntry)) + .thenReturn(Lists.newArrayList(wepWifiEntry)); launchActivity(); + ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged()); + mDevice.waitForIdle(); onView(withText(TEST_SSID)).check(matches(isDisplayed())); - ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged()); + ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged()); + mDevice.waitForIdle(); onView(withText(TEST_SSID)).check(matches(isDisplayed())); - ThreadUtils.postOnMainThread(() -> mWifiListener.onAccessPointsChanged()); + ThreadUtils.postOnMainThread(() -> mWifiListener.onWifiEntriesChanged()); + mDevice.waitForIdle(); onView(withText(TEST_SSID)).check(matches(isDisplayed())); } - - @Test - public void wrongPasswordSavedNetwork() { - setWifiState(WifiManager.WIFI_STATE_ENABLED); - - // Set up an AccessPoint that is disabled due to incorrect password. - WifiConfiguration config = new WifiConfiguration(); - config.SSID = TEST_SSID; - config.BSSID = TEST_BSSID; - config.networkId = TEST_NETWORK_ID; - config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); - - NetworkSelectionStatus selectionStatus = new NetworkSelectionStatus.Builder() - .setNetworkSelectionDisableReason( - NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD) - .setNetworkSelectionStatus( - NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED) - .build(); - config.setNetworkSelectionStatus(selectionStatus); - - WifiInfo wifiInfo = new WifiInfo.Builder() - .setSsid(TEST_UNQUOTED_SSID.getBytes(StandardCharsets.UTF_8)) - .setBssid(TEST_BSSID) - .setRssi(TEST_RSSI) - .setNetworkId(TEST_NETWORK_ID) - .build(); - AccessPoint accessPoint = new AccessPoint(mContext, config); - accessPoint.update(config, wifiInfo, null); - - // Make sure we've set up our access point correctly. - assertThat(accessPoint.getSsidStr()).isEqualTo(TEST_UNQUOTED_SSID); - assertThat(accessPoint.getBssid()).isEqualTo(TEST_BSSID); - assertThat(accessPoint.isActive()).isFalse(); - assertThat(accessPoint.getConfig()).isNotNull(); - NetworkSelectionStatus networkStatus = accessPoint.getConfig().getNetworkSelectionStatus(); - assertThat(networkStatus).isNotNull(); - assertThat(networkStatus.getNetworkSelectionStatus()) - .isEqualTo(NetworkSelectionStatus.NETWORK_SELECTION_TEMPORARY_DISABLED); - assertThat(networkStatus.getNetworkSelectionDisableReason()).isEqualTo( - NetworkSelectionStatus.DISABLED_BY_WRONG_PASSWORD); - - when(mWifiTracker.getAccessPoints()).thenReturn(Lists.newArrayList(accessPoint)); - launchActivity(WifiSettings.EXTRA_START_CONNECT_SSID, accessPoint.getSsidStr()); - - // Make sure that the password dialog is visible. - onView(withText(resourceId(STRING, WIFI_PASSWORD))).check(matches(isDisplayed())); - onView(withText(resourceId(STRING, WIFI_SHOW_PASSWORD))).check(matches(isDisplayed())); - onView(withId(resourceId(ID, PASSWORD_LAYOUT))).check(matches(isDisplayed())); - onView(withId(resourceId(ID, PASSWORD))).check(matches(isDisplayed())); - } }