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())); - } }