[Wi-Fi] Apply WifiDialog2 in WifiSetings2

This change also implements context menu in WifiSettings2.

Bug: 70983952
Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=WifiSettings2Test
Change-Id: I13b5a3724207f76e2b24fd0c1c49a236ee0c44f0
This commit is contained in:
Arc Wang
2019-12-23 18:13:18 +08:00
parent b33190c017
commit 8692bb5924
5 changed files with 694 additions and 34 deletions

View File

@@ -0,0 +1,238 @@
/*
* 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.net.ConnectivityManager;
import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process;
import android.os.SimpleClock;
import android.os.SystemClock;
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.settings.wifi.details2.WifiNetworkDetailsFragment2;
import com.android.wifitrackerlib.NetworkDetailsTracker;
import com.android.wifitrackerlib.WifiEntry;
import java.time.Clock;
import java.time.ZoneOffset;
/**
* Detail page for configuring Wi-Fi network.
*
* The WifiEntry should be saved to the argument when launching this class in order to properly
* render this page.
*/
public class ConfigureWifiEntryFragment extends InstrumentedFragment implements WifiConfigUiBase2 {
private static final String TAG = "ConfigureWifiEntryFragment";
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;
// Max age of tracked WifiEntries
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
// Interval between initiating SavedNetworkTracker scans
private static final long SCAN_INTERVAL_MILLIS = 10_000;
private WifiConfigController2 mUiController;
private Button mSubmitBtn;
private Button mCancelBtn;
private WifiEntry mWifiEntry;
private NetworkDetailsTracker mNetworkDetailsTracker;
private HandlerThread mWorkerThread;
@Override
public void onAttach(Context context) {
super.onAttach(context);
setupNetworkDetailsTracker();
mWifiEntry = mNetworkDetailsTracker.getWifiEntry();
}
@Override
public void onDestroy() {
if (mWorkerThread != null) {
mWorkerThread.quit();
}
super.onDestroy();
}
@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 WifiConfigController2(this, rootView, mWifiEntry,
getMode(), false /* requestFocus */);
/**
* For this add WifiEntry 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 WifiConfigUiBase2.MODE_CONNECT;
}
@Override
public WifiConfigController2 getController() {
return mUiController;
}
@Override
public void dispatchSubmit() {
// Do nothing
}
@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() {
getActivity().finish();
}
private void setupNetworkDetailsTracker() {
if (mNetworkDetailsTracker != null) {
return;
}
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();
}
};
mNetworkDetailsTracker = NetworkDetailsTracker.createNetworkDetailsTracker(
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,
getArguments().getString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY));
}
}

View File

@@ -16,6 +16,8 @@
package com.android.settings.wifi;
import android.net.wifi.WifiConfiguration;
import com.android.wifitrackerlib.WifiEntry;
/**

View File

@@ -19,9 +19,11 @@ package com.android.settings.wifi;
import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
import android.app.Activity;
import android.app.Dialog;
import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
@@ -38,10 +40,12 @@ 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;
@@ -64,27 +68,45 @@ 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.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.search.Indexable;
import com.android.settingslib.search.SearchIndexable;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback;
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback.ConnectStatus;
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback.DisconnectStatus;
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback.ForgetStatus;
import com.android.wifitrackerlib.WifiEntry.WifiEntryCallback.SignInStatus;
import com.android.wifitrackerlib.WifiPickerTracker;
import java.time.Clock;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* UI for Wi-Fi settings screen
*/
@SearchIndexable
public class WifiSettings2 extends RestrictedSettingsFragment
implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback {
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
@@ -92,6 +114,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
@VisibleForTesting
static final int ADD_NETWORK_REQUEST = 2;
static final int CONFIG_NETWORK_REQUEST = 3;
private static final String PREF_KEY_EMPTY_WIFI_LIST = "wifi_empty_list";
// TODO(b/70983952): Rename these to use WifiEntry instead of AccessPoint.
@@ -105,6 +128,20 @@ public class WifiSettings2 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;
private static boolean isVerboseLoggingEnabled() {
return WifiPickerTracker.isVerboseLoggingEnabled();
}
@@ -136,7 +173,7 @@ public class WifiSettings2 extends RestrictedSettingsFragment
@VisibleForTesting
WifiPickerTracker mWifiPickerTracker;
private WifiDialog mDialog;
private WifiDialog2 mDialog;
private View mProgressHeader;
@@ -275,6 +312,23 @@ public class WifiSettings2 extends RestrictedSettingsFragment
};
registerForContextMenu(getListView());
setHasOptionsMenu(true);
if (savedInstanceState != null) {
mDialogMode = savedInstanceState.getInt(SAVE_DIALOG_MODE);
mDialogWifiEntryKey = savedInstanceState.getString(SAVE_DIALOG_WIFIENTRY_KEY);
if (!TextUtils.isEmpty(mDialogWifiEntryKey)) {
List<WifiEntry> wifiEntries = mWifiPickerTracker.getWifiEntries();
Optional<WifiEntry> matchedWifiEntry = wifiEntries.stream().filter(wifiEntry ->
TextUtils.equals(wifiEntry.getKey(), mDialogWifiEntryKey)).findAny();
if (matchedWifiEntry.isPresent()) {
mDialogWifiEntry = matchedWifiEntry.get();
} else {
throw new IllegalStateException("Failed to restore WifiEntry of key: "
+ mDialogWifiEntryKey);
}
}
}
}
@Override
@@ -361,6 +415,16 @@ public class WifiSettings2 extends RestrictedSettingsFragment
}
}
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.save(wifiConfiguration,
new WifiSaveThenConnectActionListener(wifiConfiguration));
}
}
return;
}
final boolean formerlyRestricted = mIsRestricted;
@@ -384,17 +448,73 @@ public class WifiSettings2 extends RestrictedSettingsFragment
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) {
// TODO(b/70983952): Add context menu options here. This should be driven by the appropriate
// "can do action" APIs from WifiEntry.
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 (mSelectedWifiEntry.canForget()) {
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);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
// TODO(b/70983952): Add context menu selection logic here. This should simply call the
// appropriate WifiEntry action APIs (connect, forget, disconnect, etc).
return false;
switch (item.getItemId()) {
case MENU_ID_CONNECT:
connect(mSelectedWifiEntry, true /* editIfNoConfig */, false /* fullScreenEdit */);
return true;
case MENU_ID_DISCONNECT:
mSelectedWifiEntry.disconnect();
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
@@ -405,12 +525,10 @@ public class WifiSettings2 extends RestrictedSettingsFragment
return super.onPreferenceTreeClick(preference);
}
// TODO(b/70983952) Add WifiEntry click logic. This should be as simple as calling
// WifiEntry.connect().
if (preference instanceof LongPressWifiEntryPreference) {
final WifiEntry selectedEntry =
((LongPressWifiEntryPreference) preference).getWifiEntry();
selectedEntry.connect();
connect(selectedEntry, true /* editIfNoConfig */, true /* fullScreenEdit */);
} else if (preference == mAddWifiNetworkPreference) {
onAddNetworkPressed();
} else {
@@ -419,6 +537,54 @@ public class WifiSettings2 extends RestrictedSettingsFragment
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;
}
/** Called when the state of Wifi has changed. */
@Override
public void onWifiStateChanged() {
@@ -584,7 +750,8 @@ public class WifiSettings2 extends RestrictedSettingsFragment
.launch();
}
private LongPressWifiEntryPreference createLongPressWifiEntryPreference(WifiEntry wifiEntry) {
@VisibleForTesting
LongPressWifiEntryPreference createLongPressWifiEntryPreference(WifiEntry wifiEntry) {
return new LongPressWifiEntryPreference(getPrefContext(), wifiEntry, this);
}
@@ -715,6 +882,88 @@ public class WifiSettings2 extends RestrictedSettingsFragment
return R.string.help_url_wifi;
}
@Override
public void onForget(WifiDialog2 dialog) {
forget(mDialogWifiEntry);
}
@Override
public void onSubmit(WifiDialog2 dialog) {
final int dialogMode = mDialog.getController().getMode();
if (dialogMode == WifiConfigUiBase2.MODE_MODIFY) {
mWifiManager.save(mDialogWifiEntry.getWifiConfiguration(), mSaveListener);
} else if (dialogMode == WifiConfigUiBase2.MODE_CONNECT
|| (dialogMode == WifiConfigUiBase2.MODE_VIEW && mDialogWifiEntry.canConnect())) {
connect(mDialogWifiEntry, false /* editIfNoConfig */, false /* fullScreenEdit*/);
}
}
@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();
}
private 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
// WifiEntryCallback#onConnectResult with
// WifiEntryCallback#CONNECT_STATUS_FAILURE_NO_CONFIG
wifiEntry.setListener(new WifiEntryConnectCallback(wifiEntry, editIfNoConfig,
fullScreenEdit));
wifiEntry.connect();
}
private class WifiSaveThenConnectActionListener implements WifiManager.ActionListener {
final WifiConfiguration mWifiConfiguration;
WifiSaveThenConnectActionListener(WifiConfiguration wifiConfiguration) {
mWifiConfiguration = wifiConfiguration;
}
@Override
public void onSuccess() {
mWifiManager.connect(mWifiConfiguration, new WifiConnectActionListener());
}
@Override
public void onFailure(int reason) {
final Activity activity = getActivity();
if (isFisishingOrDestroyed(activity)) {
return;
}
Toast.makeText(activity, R.string.wifi_failed_save_message, Toast.LENGTH_SHORT).show();
}
};
private class WifiConnectActionListener implements WifiManager.ActionListener {
@Override
public void onSuccess() {
// Do nothing.
}
@Override
public void onFailure(int reason) {
final Activity activity = getActivity();
if (isFisishingOrDestroyed(activity)) {
return;
}
Toast.makeText(activity, R.string.wifi_failed_connect_message, Toast.LENGTH_SHORT)
.show();
}
};
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
@@ -736,4 +985,72 @@ public class WifiSettings2 extends RestrictedSettingsFragment
return result;
}
};
private class WifiEntryConnectCallback implements WifiEntryCallback {
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 onUpdated() {
// Do nothing.
}
@Override
public void onConnectResult(@ConnectStatus int status) {
final Activity activity = getActivity();
if (isFisishingOrDestroyed(activity)) {
return;
}
if (status == WifiEntryCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
if (mEditIfNoConfig) {
// Edit an unsaved secure Wi-Fi network.
if (mFullScreenEdit) {
final Bundle bundle = new Bundle();
bundle.putString(WifiNetworkDetailsFragment2.KEY_CHOSEN_WIFIENTRY_KEY,
mConnectWifiEntry.getKey());
new SubSettingLauncher(getContext())
.setTitleText(mConnectWifiEntry.getTitle())
.setDestination(ConfigureWifiEntryFragment.class.getName())
.setArguments(bundle)
.setSourceMetricsCategory(getMetricsCategory())
.setResultListener(WifiSettings2.this, CONFIG_NETWORK_REQUEST)
.launch();
} else {
showDialog(mConnectWifiEntry, WifiConfigUiBase2.MODE_MODIFY);
}
}
} else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
Toast.makeText(getContext(), R.string.wifi_failed_connect_message,
Toast.LENGTH_SHORT).show();
}
}
@Override
public void onDisconnectResult(@DisconnectStatus int status) {
// Do nothing.
}
@Override
public void onForgetResult(@ForgetStatus int status) {
// Do nothing.
}
@Override
public void onSignInResult(@SignInStatus int status) {
// Do nothing.
}
}
private boolean isFisishingOrDestroyed(Activity activity) {
return activity == null || activity.isFinishing() || activity.isDestroyed();
}
}

View File

@@ -0,0 +1,96 @@
/*
* 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.Ignore;
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;
// TODO(b/70983952): Can't test because b/146802959, should remove @Ignore tag after it's fixed.
@Ignore
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowConnectivityManager.class)
public class ConfigureWifiEntryFragmentTest {
private static final String KEY_SSID = "key_ssid";
private static final String KEY_SECURITY = "key_security";
private ConfigureWifiEntryFragment mConfigureWifiEntryFragment;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Bundle bundle = new Bundle();
bundle.putString(KEY_SSID, "Test AP");
bundle.putInt(KEY_SECURITY, 1 /* WEP */);
mConfigureWifiEntryFragment = spy(new ConfigureWifiEntryFragment());
mConfigureWifiEntryFragment.setArguments(bundle);
FragmentController.setupFragment(mConfigureWifiEntryFragment);
}
@Test
public void getMetricsCategory_shouldReturnConfigureNetwork() {
assertThat(mConfigureWifiEntryFragment.getMetricsCategory()).isEqualTo(
SettingsEnums.SETTINGS_WIFI_CONFIGURE_NETWORK);
}
@Test
public void getMode_shouldBeModeConnected() {
assertThat(mConfigureWifiEntryFragment.getMode()).isEqualTo(
WifiConfigUiBase.MODE_CONNECT);
}
@Test
public void launchFragment_shouldShowSubmitButton() {
assertThat(mConfigureWifiEntryFragment.getSubmitButton()).isNotNull();
}
@Test
public void launchFragment_shouldShowCancelButton() {
assertThat(mConfigureWifiEntryFragment.getCancelButton()).isNotNull();
}
@Test
public void onClickSubmitButton_shouldHandleSubmitAction() {
mConfigureWifiEntryFragment.getSubmitButton().performClick();
verify(mConfigureWifiEntryFragment).handleSubmitAction();
}
@Test
public void onClickCancelButton_shouldHandleCancelAction() {
mConfigureWifiEntryFragment.getCancelButton().performClick();
verify(mConfigureWifiEntryFragment).handleCancelAction();
}
}

View File

@@ -36,6 +36,8 @@ 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;
@@ -47,9 +49,12 @@ import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settingslib.search.SearchIndexableRaw;
import com.android.settingslib.wifi.LongPressWifiEntryPreference;
import com.android.wifitrackerlib.WifiEntry;
import com.android.wifitrackerlib.WifiPickerTracker;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -249,26 +254,28 @@ public class WifiSettings2Test {
assertThat(adapter.hasStableIds()).isTrue();
}
// TODO(b/70983952): Add test for context menu
// @Test
// public void onCreateContextMenu_shouldHaveForgetMenuForConnectedAccessPreference() {
// final FragmentActivity mockActivity = mock(FragmentActivity.class);
// when(mockActivity.getApplicationContext()).thenReturn(mContext);
// when(mWifiSettings2.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 =
// mWifiSettings2.createConnectedAccessPointPreference(accessPoint, mContext);
// final View view = mock(View.class);
// when(view.getTag()).thenReturn(connectedPreference);
//
// final ContextMenu menu = mock(ContextMenu.class);
// mWifiSettings2.onCreateContextMenu(menu, view, null /* info */);
//
// verify(menu).add(anyInt(), eq(WifiSettings.MENU_ID_FORGET), anyInt(), anyInt());
// }
//TODO(b/70983952): Remove @Ignore when WifiEntry API is constructed.
@Test
@Ignore
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.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());
}
}