Add NetworkRequestDialogActivity
Framwork will call this activity to start network requesting process.
This activity is simple activity contained NetworkRequestDialogFragment
and any other dialog generated in this process, aka
NetworkRequestTimeoutDialog.
Bug: 117399926
Test: RunSettingsRoboTests
Change-Id: Ib1df28d12427ed3bd7d4b88ec10e52357564c797
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2d2f584..eae1730 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -2585,6 +2585,18 @@
</intent-filter>
</activity>
+ <activity
+ android:name=".wifi.NetworkRequestDialogActivity"
+ android:theme="@style/Transparent"
+ android:excludeFromRecents="true"
+ android:exported="true"
+ android:permission="android.permission.NETWORK_SETTINGS">
+ <intent-filter>
+ <action android:name="com.android.settings.wifi.NETWORK_REQUEST" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".sim.SimDialogActivity"
android:theme="@style/Theme.AlertDialog"
android:label="@string/sim_settings_title"
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogActivity.java b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
new file mode 100644
index 0000000..5d89f77
--- /dev/null
+++ b/src/com/android/settings/wifi/NetworkRequestDialogActivity.java
@@ -0,0 +1,38 @@
+/*
+ * 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.os.Bundle;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
+
+/**
+ * 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}.
+ */
+public class NetworkRequestDialogActivity extends FragmentActivity {
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final NetworkRequestDialogFragment fragment = NetworkRequestDialogFragment.newInstance();
+ fragment.show(getSupportFragmentManager(), "NetworkRequestDialogFragment");
+ }
+}
diff --git a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
index 7078ae0..a1d8620 100644
--- a/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
+++ b/src/com/android/settings/wifi/NetworkRequestDialogFragment.java
@@ -28,9 +28,11 @@
import android.os.Handler;
import android.os.Message;
import android.widget.BaseAdapter;
+
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.internal.PreferenceImageView;
+
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -38,257 +40,276 @@
import android.widget.ArrayAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
+
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
import com.android.settingslib.Utils;
import com.android.settingslib.wifi.AccessPoint;
+
import java.util.ArrayList;
import java.util.List;
public class NetworkRequestDialogFragment extends InstrumentedDialogFragment implements
- DialogInterface.OnClickListener, NetworkRequestMatchCallback {
+ 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;
+ /** Message sent to us 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;
+ /** Delayed time to stop scanning wifi. */
+ private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
- private List<AccessPoint> mAccessPointList;
- private AccessPointAdapter mDialogAdapter;
- private NetworkRequestUserSelectionCallback mUserSelectionCallback;
+ private List<AccessPoint> mAccessPointList;
+ private AccessPointAdapter mDialogAdapter;
+ private NetworkRequestUserSelectionCallback mUserSelectionCallback;
- public static NetworkRequestDialogFragment newInstance() {
- NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
- return dialogFragment;
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Context context = getContext();
-
- // Prepares title.
- 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(R.string.network_connection_request_dialog_title);
- final ProgressBar progressBar = customTitle.findViewById(R.id.network_request_title_progress);
- progressBar.setVisibility(View.VISIBLE);
-
- // Prepares adapter.
- mDialogAdapter = new AccessPointAdapter(context,
- R.layout.preference_access_point, getAccessPointList());
-
- final AlertDialog.Builder builder = new AlertDialog.Builder(context)
- .setCustomTitle(customTitle)
- .setAdapter(mDialogAdapter, this)
- .setPositiveButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
- return builder.create();
- }
-
- @NonNull
- List<AccessPoint> getAccessPointList() {
- // Initials list for adapter, in case of display crashing.
- if (mAccessPointList == null) {
- mAccessPointList = new ArrayList<>();
- }
- return mAccessPointList;
- }
-
- private BaseAdapter getDialogAdapter() {
- return mDialogAdapter;
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final List<AccessPoint> accessPointList = getAccessPointList();
- if (accessPointList.size() == 0) {
- return; // Invalid values.
- }
- if (mUserSelectionCallback == null) {
- return; // Callback is missing or not ready.
- }
-
- if (which < accessPointList.size()) {
- WifiConfiguration wifiConfig = accessPointList.get(which).getConfig();
- mUserSelectionCallback.select(wifiConfig);
- }
- }
-
- @Override
- 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);
- }
- }
-
- @Override
- 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);
- }
-
- 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);
- stopScanningAndPopTimeoutDialog();
- break;
- default:
- // Do nothing.
- break;
- }
- }
- };
-
- protected void stopScanningAndPopTimeoutDialog() {
- // Dismisses current dialog.
- dismiss();
-
- // Throws new timeout dialog.
- final NetworkRequestTimeoutDialogFragment fragment = NetworkRequestTimeoutDialogFragment
- .newInstance();
- fragment.show(getActivity().getSupportFragmentManager(), null);
- }
-
- @Override
- public int getMetricsCategory() {
- return MetricsProto.MetricsEvent.WIFI_SCANNING_NEEDED_DIALOG;
- }
-
- private class AccessPointAdapter extends ArrayAdapter<AccessPoint> {
-
- private final int mResourceId;
- private final LayoutInflater mInflater;
-
- public AccessPointAdapter(Context context, int resourceId, List<AccessPoint> objects) {
- super(context, resourceId, objects);
- mResourceId = resourceId;
- mInflater = LayoutInflater.from(context);
+ public static NetworkRequestDialogFragment newInstance() {
+ NetworkRequestDialogFragment dialogFragment = new NetworkRequestDialogFragment();
+ return dialogFragment;
}
@Override
- public View getView(int position, View view, ViewGroup parent) {
- if (view == null) {
- view = mInflater.inflate(mResourceId, parent, false);
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Context context = getContext();
- final View divider = view.findViewById(com.android.settingslib.R.id.two_target_divider);
- divider.setVisibility(View.GONE);
- }
+ // Prepares title.
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ final View customTitle = inflater.inflate(R.layout.network_request_dialog_title, null);
- final AccessPoint accessPoint = getItem(position);
+ final TextView title = customTitle.findViewById(R.id.network_request_title_text);
+ title.setText(R.string.network_connection_request_dialog_title);
+ final ProgressBar progressBar = customTitle.findViewById(
+ R.id.network_request_title_progress);
+ progressBar.setVisibility(View.VISIBLE);
- final TextView titleView = view.findViewById(android.R.id.title);
- if (titleView != null) {
- titleView.setText(accessPoint.getSsidStr());
- }
+ // Prepares adapter.
+ mDialogAdapter = new AccessPointAdapter(context,
+ R.layout.preference_access_point, getAccessPointList());
- final TextView summary = view.findViewById(android.R.id.summary);
- if (summary != null) {
- summary.setText(accessPoint.getSettingsSummary());
- }
+ final AlertDialog.Builder builder = new AlertDialog.Builder(context)
+ .setCustomTitle(customTitle)
+ .setAdapter(mDialogAdapter, this)
+ .setPositiveButton(R.string.cancel, (dialog, which) -> getActivity().finish());
- final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
- final int level = accessPoint.getLevel();
- if (imageView != null) {
- final Drawable drawable = getContext().getDrawable(Utils.getWifiIconResource(level));
- drawable.setTintList(Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal));
- imageView.setImageDrawable(drawable);
- }
-
- return view;
- }
- }
-
- @Override
- public void onAbort() {
- // TODO(b/117399926): We should have a UI notify user here.
- }
-
- @Override
- public void onUserSelectionCallbackRegistration(
- NetworkRequestUserSelectionCallback userSelectionCallback) {
- mUserSelectionCallback = userSelectionCallback;
- }
-
- @Override
- public void onMatch(List<ScanResult> scanResults) {
- // TODO(b/119846365): Checks if we could escalate the converting effort.
- // Converts ScanResult to WifiConfiguration.
- List<WifiConfiguration> wifiConfigurations = null;
- final WifiManager wifiManager = getContext().getApplicationContext()
- .getSystemService(WifiManager.class);
- if (wifiManager != null) {
- wifiConfigurations = wifiManager.getAllMatchingWifiConfigs(scanResults);
+ // Clicking list item is to connect wifi ap.
+ final AlertDialog dialog = builder.create();
+ dialog.getListView()
+ .setOnItemClickListener(
+ (parent, view, position, id) -> this.onClick(dialog, position));
+ return dialog;
}
- setUpAccessPointList(wifiConfigurations);
-
- if (getDialogAdapter() != null) {
- getDialogAdapter().notifyDataSetChanged();
- }
- }
-
- @Override
- public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
- if (getDialogAdapter() != null) {
- updateAccessPointListItem(wificonfiguration);
- getDialogAdapter().notifyDataSetChanged();
- }
- }
-
- @Override
- public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
- if (mDialogAdapter != null) {
- updateAccessPointListItem(wificonfiguration);
- getDialogAdapter().notifyDataSetChanged();
- }
- }
-
- private void updateAccessPointListItem(WifiConfiguration wificonfiguration) {
- if (wificonfiguration == null) {
- return;
+ @NonNull
+ List<AccessPoint> getAccessPointList() {
+ // Initials list for adapter, in case of display crashing.
+ if (mAccessPointList == null) {
+ mAccessPointList = new ArrayList<>();
+ }
+ return mAccessPointList;
}
- final List<AccessPoint> accessPointList = getAccessPointList();
- final int accessPointListSize = accessPointList.size();
-
- for (int i = 0; i < accessPointListSize; i++) {
- AccessPoint accessPoint = accessPointList.get(i);
- // It is the same AccessPoint SSID, and should be replaced to update latest properties.
- if (accessPoint.matches(wificonfiguration)) {
- accessPointList.set(i, new AccessPoint(getContext(), wificonfiguration));
- break;
- }
- }
- }
-
- private void setUpAccessPointList(List<WifiConfiguration> wifiConfigurations) {
- // Grants for zero size input, since maybe current wifi is off or somethings are wrong.
- if (wifiConfigurations == null) {
- return;
+ private BaseAdapter getDialogAdapter() {
+ return mDialogAdapter;
}
- final List<AccessPoint> accessPointList = getAccessPointList();
- accessPointList.clear();
- for (WifiConfiguration config : wifiConfigurations) {
- accessPointList.add(new AccessPoint(getContext(), config));
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ final List<AccessPoint> accessPointList = getAccessPointList();
+ if (accessPointList.size() == 0) {
+ return; // Invalid values.
+ }
+ if (mUserSelectionCallback == null) {
+ return; // Callback is missing or not ready.
+ }
+
+ if (which < accessPointList.size()) {
+ WifiConfiguration wifiConfig = accessPointList.get(which).getConfig();
+ mUserSelectionCallback.select(wifiConfig);
+ }
}
- }
-}
\ No newline at end of file
+
+ @Override
+ public void onCancel(@NonNull DialogInterface dialog) {
+ super.onCancel(dialog);
+ // Finishes activity when user clicks back key or outside of dialog.
+ getActivity().finish();
+ }
+
+ @Override
+ 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);
+ }
+ }
+
+ @Override
+ 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);
+ }
+
+ 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);
+ stopScanningAndPopTimeoutDialog();
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+ }
+ };
+
+ protected void stopScanningAndPopTimeoutDialog() {
+ // Dismisses current dialog.
+ dismiss();
+
+ // Throws new timeout dialog.
+ final NetworkRequestTimeoutDialogFragment fragment = NetworkRequestTimeoutDialogFragment
+ .newInstance();
+ fragment.show(getActivity().getSupportFragmentManager(), null);
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.WIFI_SCANNING_NEEDED_DIALOG;
+ }
+
+ private class AccessPointAdapter extends ArrayAdapter<AccessPoint> {
+
+ private final int mResourceId;
+ private final LayoutInflater mInflater;
+
+ public AccessPointAdapter(Context context, int resourceId, List<AccessPoint> objects) {
+ super(context, resourceId, objects);
+ mResourceId = resourceId;
+ mInflater = LayoutInflater.from(context);
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null) {
+ view = mInflater.inflate(mResourceId, parent, false);
+
+ final View divider = view.findViewById(
+ com.android.settingslib.R.id.two_target_divider);
+ divider.setVisibility(View.GONE);
+ }
+
+ final AccessPoint accessPoint = getItem(position);
+
+ final TextView titleView = view.findViewById(android.R.id.title);
+ if (titleView != null) {
+ titleView.setText(accessPoint.getSsidStr());
+ }
+
+ final TextView summary = view.findViewById(android.R.id.summary);
+ if (summary != null) {
+ summary.setText(accessPoint.getSettingsSummary());
+ }
+
+ final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
+ final int level = accessPoint.getLevel();
+ if (imageView != null) {
+ final Drawable drawable = getContext().getDrawable(
+ Utils.getWifiIconResource(level));
+ drawable.setTintList(
+ Utils.getColorAttr(getContext(), android.R.attr.colorControlNormal));
+ imageView.setImageDrawable(drawable);
+ }
+
+ return view;
+ }
+ }
+
+ @Override
+ public void onAbort() {
+ // TODO(b/117399926): We should have a UI notify user here.
+ }
+
+ @Override
+ public void onUserSelectionCallbackRegistration(
+ NetworkRequestUserSelectionCallback userSelectionCallback) {
+ mUserSelectionCallback = userSelectionCallback;
+ }
+
+ @Override
+ public void onMatch(List<ScanResult> scanResults) {
+ // TODO(b/119846365): Checks if we could escalate the converting effort.
+ // Converts ScanResult to WifiConfiguration.
+ List<WifiConfiguration> wifiConfigurations = null;
+ final WifiManager wifiManager = getContext().getApplicationContext()
+ .getSystemService(WifiManager.class);
+ if (wifiManager != null) {
+ wifiConfigurations = wifiManager.getAllMatchingWifiConfigs(scanResults);
+ }
+
+ setUpAccessPointList(wifiConfigurations);
+
+ if (getDialogAdapter() != null) {
+ getDialogAdapter().notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
+ if (getDialogAdapter() != null) {
+ updateAccessPointListItem(wificonfiguration);
+ getDialogAdapter().notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
+ if (mDialogAdapter != null) {
+ updateAccessPointListItem(wificonfiguration);
+ getDialogAdapter().notifyDataSetChanged();
+ }
+ }
+
+ private void updateAccessPointListItem(WifiConfiguration wificonfiguration) {
+ if (wificonfiguration == null) {
+ return;
+ }
+
+ final List<AccessPoint> accessPointList = getAccessPointList();
+ final int accessPointListSize = accessPointList.size();
+
+ for (int i = 0; i < accessPointListSize; i++) {
+ AccessPoint accessPoint = accessPointList.get(i);
+ // It is the same AccessPoint SSID, and should be replaced to update latest properties.
+ if (accessPoint.matches(wificonfiguration)) {
+ accessPointList.set(i, new AccessPoint(getContext(), wificonfiguration));
+ break;
+ }
+ }
+ }
+
+ private void setUpAccessPointList(List<WifiConfiguration> wifiConfigurations) {
+ // Grants for zero size input, since maybe current wifi is off or somethings are wrong.
+ if (wifiConfigurations == null) {
+ return;
+ }
+
+ final List<AccessPoint> accessPointList = getAccessPointList();
+ accessPointList.clear();
+ for (WifiConfiguration config : wifiConfigurations) {
+ accessPointList.add(new AccessPoint(getContext(), config));
+ }
+ }
+}
diff --git a/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
new file mode 100644
index 0000000..4889c83
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/wifi/NetworkRequestDialogActivityTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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 static com.google.common.truth.Truth.assertThat;
+
+import androidx.appcompat.app.AlertDialog;
+
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl;
+import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.Robolectric;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(shadows = {
+ ShadowAlertDialogCompat.class,
+ SettingsShadowResourcesImpl.class
+})
+public class NetworkRequestDialogActivityTest {
+
+ @Test
+ public void LaunchActivity_shouldShowNetworkRequestDialog() {
+ NetworkRequestDialogActivity activity = Robolectric
+ .setupActivity(NetworkRequestDialogActivity.class);
+
+ AlertDialog alertDialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+
+ assertThat(alertDialog.isShowing()).isTrue();
+ }
+}