diff --git a/res/values/strings.xml b/res/values/strings.xml index cacb8829e72..a7d56856484 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11138,6 +11138,10 @@ Connection successful Show all + + Searching for device\u2026 + + Connecting to device\u2026 diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java index 5d89f7771a1..d917b03024f 100644 --- a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java +++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java @@ -16,23 +16,242 @@ package com.android.settings.wifi; +import android.app.ProgressDialog; +import android.content.Intent; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.NetworkRequestMatchCallback; +import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.os.Bundle; - +import android.os.Handler; +import android.os.Message; +import android.widget.Toast; import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentActivity; +import com.android.settings.R; +import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; +import java.util.List; /** * When other applications request to have a wifi connection, framework will bring up this activity - * to let user select which wifi ap wanna to connect. This activity is just a door for framework - * call, and main functional process is at {@code NetworkRequestDialogFragment}. + * to let user select which wifi ap wanna to connect. This activity contains + * {@code NetworkRequestDialogFragment}, {@code NetworkRequestSingleSsidDialogFragment} to show UI + * and handles framework callback. */ -public class NetworkRequestDialogActivity extends FragmentActivity { +public class NetworkRequestDialogActivity extends FragmentActivity implements + NetworkRequestMatchCallback { + private static String TAG = "NetworkRequestDialogActivity"; + + /** Message sent to stop scanning wifi and pop up timeout dialog. */ + private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0; + + /** Delayed time to stop scanning wifi. */ + private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000; + + final static String EXTRA_IS_SPECIFIED_SSID = + "com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK"; + + private NetworkRequestDialogBaseFragment mDialogFragment; + private NetworkRequestUserSelectionCallback mUserSelectionCallback; + private boolean mIsSpecifiedSsid; + private boolean mShowingErrorDialog; + private WifiConfiguration mMatchedConfig; + private ProgressDialog mProgressDialog; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - final NetworkRequestDialogFragment fragment = NetworkRequestDialogFragment.newInstance(); - fragment.show(getSupportFragmentManager(), "NetworkRequestDialogFragment"); + final Intent intent = getIntent(); + if (intent != null) { + mIsSpecifiedSsid = intent.getBooleanExtra(EXTRA_IS_SPECIFIED_SSID, false); + } + + if (mIsSpecifiedSsid) { + showProgressDialog(getString(R.string.network_connection_searching_message)); + } else { + mDialogFragment = NetworkRequestDialogFragment.newInstance(); + mDialogFragment.show(getSupportFragmentManager(), TAG); + } + } + + private void showProgressDialog(String message) { + dismissDialogs(); + + mProgressDialog = new ProgressDialog(this); + mProgressDialog.setIndeterminate(true); + mProgressDialog.setCancelable(false); + mProgressDialog.setMessage(message); + mProgressDialog.show(); + } + + private void showSingleSsidRequestDialog(String ssid, boolean isTryAgain) { + dismissDialogs(); + + mDialogFragment = new NetworkRequestSingleSsidDialogFragment(); + final Bundle bundle = new Bundle(); + bundle.putString(NetworkRequestSingleSsidDialogFragment.EXTRA_SSID, ssid); + bundle.putBoolean(NetworkRequestSingleSsidDialogFragment.EXTRA_TRYAGAIN, isTryAgain); + mDialogFragment.setArguments(bundle); + mDialogFragment.show(getSupportFragmentManager(), TAG); + } + + private void dismissDialogs() { + if (mDialogFragment != null) { + mDialogFragment.dismiss(); + mDialogFragment = null; + } + if (mProgressDialog != null) { + mProgressDialog.dismiss(); + mProgressDialog = null; + } + } + + @Override + protected void onResume() { + super.onResume(); + + final WifiManager wifiManager = getSystemService(WifiManager.class); + if (wifiManager != null) { + wifiManager.registerNetworkRequestMatchCallback(this, mHandler); + } + // Sets time-out to stop scanning. + mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS); + } + + @Override + protected void onPause() { + mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); + final WifiManager wifiManager = getSystemService(WifiManager.class); + if (wifiManager != null) { + wifiManager.unregisterNetworkRequestMatchCallback(this); + } + + super.onPause(); + } + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MESSAGE_STOP_SCAN_WIFI_LIST: + removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); + stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT); + break; + default: + // Do nothing. + break; + } + } + }; + + protected void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) { + dismissDialogs(); + + // Throws error dialog. + final DialogFragment dialogFragment = NetworkRequestErrorDialogFragment.newInstance(); + final Bundle bundle = new Bundle(); + bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type); + dialogFragment.setArguments(bundle); + dialogFragment.show(getSupportFragmentManager(), TAG); + mShowingErrorDialog = true; + } + + @Override + public void onUserSelectionCallbackRegistration( + NetworkRequestUserSelectionCallback userSelectionCallback) { + if (mIsSpecifiedSsid) { + mUserSelectionCallback = userSelectionCallback; + return; + } + + mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback); + } + + @Override + public void onAbort() { + stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT); + } + + @Override + public void onMatch(List scanResults) { + if (mShowingErrorDialog) { + // Don't do anything since error dialog shows. + return; + } + + mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); + + if (mIsSpecifiedSsid) { + // Prevent from throwing same dialog, because onMatch() will be called many times. + if (mMatchedConfig == null) { + mMatchedConfig = WifiUtils.getWifiConfig( + null /* accesspoint */, scanResults.get(0), null /* password */); + showSingleSsidRequestDialog( + WifiInfo.removeDoubleQuotes(mMatchedConfig.SSID), false /* isTryAgain */); + } + return; + } + + mDialogFragment.onMatch(scanResults); + } + + @Override + public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) { + if (!isFinishing()) { + Toast.makeText(this, R.string.network_connection_connect_successful, + Toast.LENGTH_SHORT).show(); + setResult(RESULT_OK); + finish(); + } + } + + @Override + public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) { + if (mIsSpecifiedSsid) { + showSingleSsidRequestDialog( + WifiInfo.removeDoubleQuotes(mMatchedConfig.SSID), true /* isTryAgain */); + return; + } + + mDialogFragment.onUserSelectionConnectFailure(wificonfiguration); + } + + // Called when user click "Connect" button. Called by + // {@code NetworkRequestSingleSsidDialogFragment}. + public void onClickConnectButton() { + if (mUserSelectionCallback != null) { + mUserSelectionCallback.select(mMatchedConfig); + showProgressDialog(getString(R.string.network_connection_connecting_message)); + } + } + + // Called when user click retry button. Called by {@link NetworkRequestErrorDialogFragment}. + public void onClickRescanButton() { + // Sets time-out to stop scanning. + mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS); + + mShowingErrorDialog = false; + + if (mIsSpecifiedSsid) { + mMatchedConfig = null; + showProgressDialog(getString(R.string.network_connection_searching_message)); + } else { + mDialogFragment = NetworkRequestDialogFragment.newInstance(); + mDialogFragment.show(getSupportFragmentManager(), TAG); + } + } + + // Called when user click cancel button. + public void onCancel() { + dismissDialogs(); + + if (mUserSelectionCallback != null) { + mUserSelectionCallback.reject(); + } + finish(); } } diff --git a/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java new file mode 100644 index 00000000000..eda3204a715 --- /dev/null +++ b/src/com/android/settings/wifi/NetworkRequestDialogBaseFragment.java @@ -0,0 +1,90 @@ +/* + * 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.settings.SettingsEnums; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import com.android.settings.R; +import com.android.settings.core.instrumentation.InstrumentedDialogFragment; +import java.util.List; + +/** + * This is base fragment of {@link NetworkRequestDialogFragment} and + * {@link NetworkRequestSingleSsidDialogFragment} to handle activity callback methods. + */ +abstract public class NetworkRequestDialogBaseFragment extends InstrumentedDialogFragment { + + @VisibleForTesting + final static String EXTRA_APP_NAME = "com.android.settings.wifi.extra.APP_NAME"; + + NetworkRequestDialogActivity mActivity = null; + + protected String getTitle() { + final Intent intent = getActivity().getIntent(); + String appName = ""; + if (intent != null) { + appName = intent.getStringExtra(EXTRA_APP_NAME); + } + + return getString(R.string.network_connection_request_dialog_title, appName); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.WIFI_SCANNING_NEEDED_DIALOG; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof NetworkRequestDialogActivity) { + mActivity = (NetworkRequestDialogActivity) context; + } + } + + @Override + public void onDetach() { + super.onDetach(); + mActivity = null; + } + + @Override + public void onCancel(@NonNull DialogInterface dialog) { + super.onCancel(dialog); + + if (mActivity != null) { + mActivity.onCancel(); + } + } + + protected void onUserSelectionCallbackRegistration( + NetworkRequestUserSelectionCallback userSelectionCallback) { + } + + protected void onMatch(List scanResults) { + } + + protected void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) { + } +} diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java index eb7d78fd789..a88b004b445 100644 --- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java +++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java @@ -16,21 +16,15 @@ package com.android.settings.wifi; -import android.app.Activity; import android.app.Dialog; -import android.app.settings.SettingsEnums; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.graphics.drawable.Drawable; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; -import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.NetworkRequestMatchCallback; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.os.Bundle; -import android.os.Handler; -import android.os.Message; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -40,22 +34,16 @@ import android.widget.BaseAdapter; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; -import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import androidx.preference.internal.PreferenceImageView; - import com.android.settings.R; -import com.android.settings.core.instrumentation.InstrumentedDialogFragment; -import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; import com.android.settingslib.Utils; import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.wifi.AccessPoint; import com.android.settingslib.wifi.WifiTracker; import com.android.settingslib.wifi.WifiTrackerFactory; - import java.util.ArrayList; import java.util.List; @@ -64,11 +52,8 @@ import java.util.List; * behaviors of the callback when requesting wifi network, except for error message. When error * happens, {@link NetworkRequestErrorDialogFragment} will be called to display error message. */ -public class NetworkRequestDialogFragment extends InstrumentedDialogFragment implements - DialogInterface.OnClickListener, NetworkRequestMatchCallback { - - /** Message sent to us to stop scanning wifi and pop up timeout dialog. */ - private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0; +public class NetworkRequestDialogFragment extends NetworkRequestDialogBaseFragment implements + DialogInterface.OnClickListener{ /** * Spec defines there should be 5 wifi ap on the list at most or just show all if {@code @@ -77,20 +62,10 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp private static final int MAX_NUMBER_LIST_ITEM = 5; private boolean mShowLimitedItem = true; - /** Delayed time to stop scanning wifi. */ - private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000; - - @VisibleForTesting - final static String EXTRA_APP_NAME = "com.android.settings.wifi.extra.APP_NAME"; - final static String EXTRA_IS_SPECIFIED_SSID = - "com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK"; - private List mAccessPointList; private FilterWifiTracker mFilterWifiTracker; private AccessPointAdapter mDialogAdapter; private NetworkRequestUserSelectionCallback mUserSelectionCallback; - private boolean mIsSpecifiedSsid; - private boolean mWaitingConnectCallback; public static NetworkRequestDialogFragment newInstance() { NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment(); @@ -108,11 +83,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp final TextView title = customTitle.findViewById(R.id.network_request_title_text); title.setText(getTitle()); - final Intent intent = getActivity().getIntent(); - if (intent != null) { - mIsSpecifiedSsid = intent.getBooleanExtra(EXTRA_IS_SPECIFIED_SSID, false); - } - final ProgressBar progressBar = customTitle.findViewById( R.id.network_request_title_progress); progressBar.setVisibility(View.VISIBLE); @@ -128,9 +98,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp // Do nothings, will replace the onClickListener to avoid auto closing dialog. .setNeutralButton(R.string.network_connection_request_dialog_showall, null /* OnClickListener */); - if (mIsSpecifiedSsid) { - builder.setPositiveButton(R.string.wifi_connect, null /* OnClickListener */); - } // Clicking list item is to connect wifi ap. final AlertDialog dialog = builder.create(); @@ -152,32 +119,10 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp notifyAdapterRefresh(); neutralBtn.setVisibility(View.GONE); }); - - // Replace Positive onClickListener to avoid closing dialog - if (mIsSpecifiedSsid) { - final Button positiveBtn = dialog.getButton(AlertDialog.BUTTON_POSITIVE); - positiveBtn.setOnClickListener(v -> { - // When clicking connect button, should connect to the first and the only one - // list item. - this.onClick(dialog, 0 /* position */); - }); - // Disable button in first, and enable it after there are some accesspoints in list. - positiveBtn.setEnabled(false); - } }); return dialog; } - private String getTitle() { - final Intent intent = getActivity().getIntent(); - String appName = ""; - if (intent != null) { - appName = intent.getStringExtra(EXTRA_APP_NAME); - } - - return getString(R.string.network_connection_request_dialog_title, appName); - } - @NonNull List getAccessPointList() { // Initials list for adapter, in case of display crashing. @@ -211,9 +156,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp if (wifiConfig != null) { mUserSelectionCallback.select(wifiConfig); - - mWaitingConnectCallback = true; - updateConnectButton(false); } } } @@ -221,10 +163,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp @Override public void onCancel(@NonNull DialogInterface dialog) { super.onCancel(dialog); - // Finishes the activity when user clicks back key or outside of the dialog. - if (getActivity() != null) { - getActivity().finish(); - } if (mUserSelectionCallback != null) { mUserSelectionCallback.reject(); } @@ -234,13 +172,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp public void onPause() { super.onPause(); - mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); - final WifiManager wifiManager = getContext().getApplicationContext() - .getSystemService(WifiManager.class); - if (wifiManager != null) { - wifiManager.unregisterNetworkRequestMatchCallback(this); - } - if (mFilterWifiTracker != null) { mFilterWifiTracker.onPause(); } @@ -268,23 +199,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp } } - private void updateConnectButton(boolean enabled) { - // The button is only showed in single SSID mode. - if (!mIsSpecifiedSsid) { - return; - } - - final AlertDialog alertDialog = (AlertDialog) getDialog(); - if (alertDialog == null) { - return; - } - - final Button positiveBtn = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE); - if (positiveBtn != null) { - positiveBtn.setEnabled(enabled); - } - } - private void hideProgressIcon() { final AlertDialog alertDialog = (AlertDialog) getDialog(); if (alertDialog == null) { @@ -301,57 +215,12 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp public void onResume() { super.onResume(); - final WifiManager wifiManager = getContext().getApplicationContext() - .getSystemService(WifiManager.class); - if (wifiManager != null) { - wifiManager.registerNetworkRequestMatchCallback(this, mHandler); - } - // Sets time-out to stop scanning. - mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS); - if (mFilterWifiTracker == null) { mFilterWifiTracker = new FilterWifiTracker(getActivity(), getSettingsLifecycle()); } mFilterWifiTracker.onResume(); } - private final Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MESSAGE_STOP_SCAN_WIFI_LIST: - removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); - stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT); - break; - default: - // Do nothing. - break; - } - } - }; - - protected void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) { - // Dismisses current dialog. - final Dialog dialog = getDialog(); - if (dialog != null && dialog.isShowing()) { - dismiss(); - } - - // Throws error dialog. - final NetworkRequestErrorDialogFragment fragment = NetworkRequestErrorDialogFragment - .newInstance(); - final Bundle bundle = new Bundle(); - bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type); - fragment.setArguments(bundle); - fragment.show(getActivity().getSupportFragmentManager(), - NetworkRequestDialogFragment.class.getSimpleName()); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.WIFI_SCANNING_NEEDED_DIALOG; - } - private class AccessPointAdapter extends ArrayAdapter { private final int mResourceId; @@ -407,11 +276,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp } } - @Override - public void onAbort() { - stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT); - } - @Override public void onUserSelectionCallbackRegistration( NetworkRequestUserSelectionCallback userSelectionCallback) { @@ -422,7 +286,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp public void onMatch(List scanResults) { // Shouldn't need to renew cached list, since input result is empty. if (scanResults != null && scanResults.size() > 0) { - mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST); renewAccessPointList(scanResults); notifyAdapterRefresh(); @@ -455,21 +318,9 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp } } - @Override - public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) { - final Activity activity = getActivity(); - if (activity != null) { - Toast.makeText(activity, R.string.network_connection_connect_successful, - Toast.LENGTH_SHORT).show(); - activity.finish(); - } - } - @Override public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) { // Do nothing when selection is failed, let user could try again easily. - mWaitingConnectCallback = false; - updateConnectButton(true); } private final class FilterWifiTracker { @@ -526,13 +377,6 @@ public class NetworkRequestDialogFragment extends InstrumentedDialogFragment imp if (count > 0) { hideProgressIcon(); } - // Enable connect button if there is Accesspoint item, except for the situation that - // user click but connected status doesn't come back yet. - if (count < 0) { - updateConnectButton(false); - } else if (!mWaitingConnectCallback) { - updateConnectButton(true); - } return result; } diff --git a/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java index 261d3131e49..731456ac5c6 100644 --- a/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java +++ b/src/com/android/settings/wifi/NetworkRequestErrorDialogFragment.java @@ -20,10 +20,8 @@ import android.app.Dialog; import android.app.settings.SettingsEnums; import android.content.DialogInterface; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; - import com.android.settings.R; import com.android.settings.core.instrumentation.InstrumentedDialogFragment; @@ -64,7 +62,7 @@ public class NetworkRequestErrorDialogFragment extends InstrumentedDialogFragmen if (msgType == ERROR_DIALOG_TYPE.TIME_OUT) { builder.setMessage(R.string.network_connection_timeout_dialog_message) .setPositiveButton(R.string.network_connection_timeout_dialog_ok, - (dialog, which) -> startScanningDialog()) + (dialog, which) -> onRescanClick()) .setNegativeButton(R.string.cancel, (dialog, which) -> getActivity().finish()); } else { builder.setMessage(R.string.network_connection_errorstate_dialog_message) @@ -78,9 +76,10 @@ public class NetworkRequestErrorDialogFragment extends InstrumentedDialogFragmen return SettingsEnums.WIFI_SCANNING_NEEDED_DIALOG; } - protected void startScanningDialog() { - final NetworkRequestDialogFragment fragment = NetworkRequestDialogFragment.newInstance(); - fragment.show(getActivity().getSupportFragmentManager(), - NetworkRequestErrorDialogFragment.class.getSimpleName()); + protected void onRescanClick() { + if (getActivity() != null) { + dismiss(); + ((NetworkRequestDialogActivity)getActivity()).onClickRescanButton(); + } } } diff --git a/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java new file mode 100644 index 00000000000..7a0ccbea58a --- /dev/null +++ b/src/com/android/settings/wifi/NetworkRequestSingleSsidDialogFragment.java @@ -0,0 +1,59 @@ +package com.android.settings.wifi; + +import android.app.Dialog; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.TextView; +import androidx.appcompat.app.AlertDialog; +import com.android.settings.R; + +/** + * This is similar fragment with {@link NetworkRequestDialogFragment} but only for single SSID mode. + */ +public class NetworkRequestSingleSsidDialogFragment extends + NetworkRequestDialogBaseFragment { + public static final String EXTRA_SSID = "DIALOG_REQUEST_SSID"; + public static final String EXTRA_TRYAGAIN = "DIALOG_IS_TRYAGAIN"; + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + boolean isTryAgain = false; + String requestSsid = ""; + if (getArguments() != null) { + isTryAgain = getArguments().getBoolean(EXTRA_TRYAGAIN, true); + requestSsid = getArguments().getString(EXTRA_SSID, ""); + } + + final Context context = getContext(); + final LayoutInflater inflater = LayoutInflater.from(context); + + final View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null); + final TextView title = customTitle.findViewById(R.id.network_request_title_text); + title.setText(getTitle()); + final ProgressBar progressBar = customTitle + .findViewById(R.id.network_request_title_progress); + progressBar.setVisibility(View.GONE); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context) + .setCustomTitle(customTitle) + .setMessage(requestSsid) + .setPositiveButton(isTryAgain ? R.string.network_connection_timeout_dialog_ok + : R.string.wifi_connect, (dialog, which) -> onUserClickConnectButton()) + .setNeutralButton(R.string.cancel, (dialog, which) -> onCancel(dialog)); + + // Don't dismiss dialog when touching outside. User reports it is easy to touch outside. + // This causes dialog to close. + setCancelable(false); + + return builder.create(); + } + + private void onUserClickConnectButton() { + if (mActivity != null) { + mActivity.onClickConnectButton(); + } + } +} diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java index 107da79d8c5..5cfc3e89163 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java @@ -17,35 +17,109 @@ package com.android.settings.wifi; import static com.google.common.truth.Truth.assertThat; - +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import android.content.Context; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiManager; +import android.os.Bundle; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; - import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; +import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; import com.android.settingslib.wifi.WifiTracker; import com.android.settingslib.wifi.WifiTrackerFactory; - +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.shadows.ShadowLooper; @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowAlertDialogCompat.class) public class NetworkRequestDialogActivityTest { - @Test - public void LaunchActivity_shouldShowNetworkRequestDialog() { - // Mocks fake WifiTracker, in case of exception in NetworkRequestDialogFragment.onResume(). + NetworkRequestDialogActivity mActivity; + WifiManager mWifiManager; + Context mContext; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + WifiTracker wifiTracker = mock(WifiTracker.class); WifiTrackerFactory.setTestingWifiTracker(wifiTracker); - Robolectric.setupActivity(NetworkRequestDialogActivity.class); + NetworkRequestDialogActivity activity = + Robolectric.setupActivity(NetworkRequestDialogActivity.class); + mActivity = spy(activity); + mWifiManager = mock(WifiManager.class); + when(mActivity.getSystemService(Context.WIFI_SERVICE)).thenReturn(mWifiManager); + } + + @Test + public void LaunchActivity_shouldShowNetworkRequestDialog() { AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog(); assertThat(alertDialog.isShowing()).isTrue(); } + + @Test + public void onResume_shouldRegisterCallback() { + mActivity.onResume(); + + verify(mWifiManager).registerNetworkRequestMatchCallback(any(), any()); + } + + @Test + public void onPause_shouldUnRegisterCallback() { + mActivity.onPause(); + + verify(mWifiManager).unregisterNetworkRequestMatchCallback(mActivity); + } + + @Test + public void onResumeAndWaitTimeout_shouldCallTimeoutDialog() { + FakeNetworkRequestDialogActivity fakeActivity = + Robolectric.setupActivity(FakeNetworkRequestDialogActivity.class); + + fakeActivity.onResume(); + ShadowLooper.getShadowMainLooper().runToEndOfTasks(); + + assertThat(fakeActivity.bCalledStopAndPop).isTrue(); + assertThat(fakeActivity.errorType).isEqualTo(ERROR_DIALOG_TYPE.TIME_OUT); + } + + public static class FakeNetworkRequestDialogActivity extends NetworkRequestDialogActivity { + boolean bCalledStopAndPop = false; + ERROR_DIALOG_TYPE errorType = null; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) { + bCalledStopAndPop = true; + errorType = type; + } + } + + @Test + public void updateAccessPointList_onUserSelectionConnectSuccess_shouldFinishActivity() { + final WifiConfiguration config = new WifiConfiguration(); + config.SSID = "Test AP 3"; + mActivity.onUserSelectionConnectSuccess(config); + + verify(mActivity).finish(); + } } diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java index 4202143db00..4f757944fcb 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogFragmentTest.java @@ -17,8 +17,6 @@ package com.android.settings.wifi; import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -29,25 +27,20 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.wifi.ScanResult; -import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView; - import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.FragmentActivity; - import com.android.settings.R; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; -import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; import com.android.settingslib.wifi.AccessPoint; - +import com.android.settingslib.wifi.WifiTracker; +import com.android.settingslib.wifi.WifiTrackerFactory; import java.util.ArrayList; import java.util.List; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -56,11 +49,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; -import com.android.settingslib.wifi.WifiTracker; -import com.android.settingslib.wifi.WifiTrackerFactory; - -import org.robolectric.shadows.ShadowLooper; - @RunWith(RobolectricTestRunner.class) @Config(shadows = ShadowAlertDialogCompat.class) public class NetworkRequestDialogFragmentTest { @@ -69,14 +57,14 @@ public class NetworkRequestDialogFragmentTest { private static final String KEY_SECURITY = "key_security"; private static final String TEST_APP_NAME = "TestAppName"; - private FragmentActivity mActivity; + private NetworkRequestDialogActivity mActivity; private NetworkRequestDialogFragment networkRequestDialogFragment; private Context mContext; private WifiTracker mWifiTracker; @Before public void setUp() { - mActivity = Robolectric.buildActivity(FragmentActivity.class, + mActivity = Robolectric.buildActivity(NetworkRequestDialogActivity.class, new Intent().putExtra(NetworkRequestDialogFragment.EXTRA_APP_NAME, TEST_APP_NAME)).setup().get(); networkRequestDialogFragment = spy(NetworkRequestDialogFragment.newInstance()); @@ -118,73 +106,6 @@ public class NetworkRequestDialogFragmentTest { assertThat(alertDialog.isShowing()).isFalse(); } - @Test - public void onResumeAndWaitTimeout_shouldCallTimeoutDialog() { - FakeNetworkRequestDialogFragment fakeFragment = new FakeNetworkRequestDialogFragment(); - FakeNetworkRequestDialogFragment spyFakeFragment = spy(fakeFragment); - spyFakeFragment.show(mActivity.getSupportFragmentManager(), null); - - assertThat(fakeFragment.bCalledStopAndPop).isFalse(); - - ShadowLooper.getShadowMainLooper().runToEndOfTasks(); - - assertThat(fakeFragment.bCalledStopAndPop).isTrue(); - assertThat(fakeFragment.errorType).isEqualTo(ERROR_DIALOG_TYPE.TIME_OUT); - } - - class FakeNetworkRequestDialogFragment extends NetworkRequestDialogFragment { - boolean bCalledStopAndPop = false; - ERROR_DIALOG_TYPE errorType = null; - - @Override - public void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) { - bCalledStopAndPop = true; - errorType = type; - } - } - - @Test - public void onResume_shouldRegisterCallback() { - when(networkRequestDialogFragment.getContext()).thenReturn(mContext); - Context applicationContext = spy(RuntimeEnvironment.application.getApplicationContext()); - when(mContext.getApplicationContext()).thenReturn(applicationContext); - WifiManager wifiManager = mock(WifiManager.class); - when(applicationContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(wifiManager); - - networkRequestDialogFragment.onResume(); - - verify(wifiManager).registerNetworkRequestMatchCallback(any(), any()); - } - - @Test - public void onPause_shouldUnRegisterCallback() { - when(networkRequestDialogFragment.getContext()).thenReturn(mContext); - Context applicationContext = spy(RuntimeEnvironment.application.getApplicationContext()); - when(mContext.getApplicationContext()).thenReturn(applicationContext); - WifiManager wifiManager = mock(WifiManager.class); - when(applicationContext.getSystemService(Context.WIFI_SERVICE)).thenReturn(wifiManager); - - networkRequestDialogFragment.onPause(); - - verify(wifiManager).unregisterNetworkRequestMatchCallback(networkRequestDialogFragment); - } - - @Test - public void updateAccessPointList_onUserSelectionConnectSuccess_shouldFinishActivity() { - // Assert - final FragmentActivity spyActivity = spy(mActivity); - when(networkRequestDialogFragment.getActivity()).thenReturn(spyActivity); - networkRequestDialogFragment.show(spyActivity.getSupportFragmentManager(), "onUserSelectionConnectSuccess"); - - // Action - final WifiConfiguration config = new WifiConfiguration(); - config.SSID = "Test AP 3"; - networkRequestDialogFragment.onUserSelectionConnectSuccess(config); - - // Check - verify(spyActivity).finish(); - } - @Test public void onUserSelectionCallbackRegistration_onClick_shouldCallSelect() { // Assert. diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java index 303f6af6721..fb15371dd99 100644 --- a/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestErrorDialogFragmentTest.java @@ -17,7 +17,7 @@ package com.android.settings.wifi; import static com.google.common.truth.Truth.assertThat; - +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.internal.verification.VerificationModeFactory.times; @@ -25,14 +25,12 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; import android.content.DialogInterface; import android.os.Bundle; import android.widget.Button; - import androidx.appcompat.app.AlertDialog; -import androidx.fragment.app.FragmentActivity; - import com.android.settings.R; import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE; - +import com.android.settingslib.wifi.WifiTracker; +import com.android.settingslib.wifi.WifiTrackerFactory; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,12 +43,15 @@ import org.robolectric.annotation.Config; @Config(shadows = ShadowAlertDialogCompat.class) public class NetworkRequestErrorDialogFragmentTest { - private FragmentActivity mActivity; + private NetworkRequestDialogActivity mActivity; private NetworkRequestErrorDialogFragment mFragment; @Before public void setUp() { - mActivity = Robolectric.setupActivity(FragmentActivity.class); + WifiTracker wifiTracker = mock(WifiTracker.class); + WifiTrackerFactory.setTestingWifiTracker(wifiTracker); + + mActivity = Robolectric.setupActivity(NetworkRequestDialogActivity.class); mFragment = spy(NetworkRequestErrorDialogFragment.newInstance()); mFragment.show(mActivity.getSupportFragmentManager(), null); } @@ -97,7 +98,7 @@ public class NetworkRequestErrorDialogFragmentTest { assertThat(positiveButton).isNotNull(); positiveButton.performClick(); - verify(mFragment, times(1)).startScanningDialog(); + verify(mFragment, times(1)).onRescanClick(); } @Test