• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.wifi;
18 
19 import android.app.ProgressDialog;
20 import android.content.Intent;
21 import android.net.wifi.ScanResult;
22 import android.net.wifi.WifiConfiguration;
23 import android.net.wifi.WifiInfo;
24 import android.net.wifi.WifiManager;
25 import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
26 import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.HandlerExecutor;
30 import android.os.Message;
31 import android.widget.Toast;
32 
33 import androidx.annotation.Nullable;
34 import androidx.fragment.app.FragmentActivity;
35 
36 import com.android.settings.R;
37 import com.android.settings.wifi.NetworkRequestErrorDialogFragment.ERROR_DIALOG_TYPE;
38 
39 import java.util.List;
40 
41 /**
42  * When other applications request to have a wifi connection, framework will bring up this activity
43  * to let user select which wifi ap wanna to connect. This activity contains
44  * {@code NetworkRequestDialogFragment}, {@code NetworkRequestSingleSsidDialogFragment} to show UI
45  * and handles framework callback.
46  */
47 public class NetworkRequestDialogActivity extends FragmentActivity implements
48         NetworkRequestMatchCallback {
49     private static String TAG = "NetworkRequestDialogActivity";
50 
51     /** Message sent to stop scanning wifi and pop up timeout dialog. */
52     private static final int MESSAGE_STOP_SCAN_WIFI_LIST = 0;
53 
54     /** Delayed time to stop scanning wifi. */
55     private static final int DELAY_TIME_STOP_SCAN_MS = 30 * 1000;
56 
57     final static String EXTRA_IS_SPECIFIED_SSID =
58         "com.android.settings.wifi.extra.REQUEST_IS_FOR_SINGLE_NETWORK";
59 
60     private NetworkRequestDialogBaseFragment mDialogFragment;
61     private NetworkRequestUserSelectionCallback mUserSelectionCallback;
62     private boolean mIsSpecifiedSsid;
63     private boolean mShowingErrorDialog;
64     private WifiConfiguration mMatchedConfig;
65     private ProgressDialog mProgressDialog;
66 
67     @Override
onCreate(@ullable Bundle savedInstanceState)68     protected void onCreate(@Nullable Bundle savedInstanceState) {
69         super.onCreate(savedInstanceState);
70 
71         final Intent intent = getIntent();
72         if (intent != null) {
73             mIsSpecifiedSsid = intent.getBooleanExtra(EXTRA_IS_SPECIFIED_SSID, false);
74         }
75 
76         if (mIsSpecifiedSsid) {
77             showProgressDialog(getString(R.string.network_connection_searching_message));
78         } else {
79             mDialogFragment = NetworkRequestDialogFragment.newInstance();
80             mDialogFragment.show(getSupportFragmentManager(), TAG);
81         }
82     }
83 
showProgressDialog(String message)84     private void showProgressDialog(String message) {
85         dismissDialogs();
86 
87         mProgressDialog = new ProgressDialog(this);
88         mProgressDialog.setIndeterminate(true);
89         mProgressDialog.setCancelable(false);
90         mProgressDialog.setMessage(message);
91         mProgressDialog.show();
92     }
93 
showSingleSsidRequestDialog(String ssid, boolean isTryAgain)94     private void showSingleSsidRequestDialog(String ssid, boolean isTryAgain) {
95         dismissDialogs();
96 
97         mDialogFragment = new NetworkRequestSingleSsidDialogFragment();
98         final Bundle bundle = new Bundle();
99         bundle.putString(NetworkRequestSingleSsidDialogFragment.EXTRA_SSID, ssid);
100         bundle.putBoolean(NetworkRequestSingleSsidDialogFragment.EXTRA_TRYAGAIN, isTryAgain);
101         mDialogFragment.setArguments(bundle);
102         mDialogFragment.show(getSupportFragmentManager(), TAG);
103     }
104 
dismissDialogs()105     private void dismissDialogs() {
106         if (mDialogFragment != null) {
107             mDialogFragment.dismiss();
108             mDialogFragment = null;
109         }
110         if (mProgressDialog != null) {
111             mProgressDialog.dismiss();
112             mProgressDialog = null;
113         }
114     }
115 
116     @Override
onResume()117     protected void onResume() {
118         super.onResume();
119 
120         final WifiManager wifiManager = getSystemService(WifiManager.class);
121         if (wifiManager != null) {
122             wifiManager.registerNetworkRequestMatchCallback(new HandlerExecutor(mHandler), this);
123         }
124         // Sets time-out to stop scanning.
125         mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
126     }
127 
128     @Override
onPause()129     protected void onPause() {
130         mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
131         final WifiManager wifiManager = getSystemService(WifiManager.class);
132         if (wifiManager != null) {
133             wifiManager.unregisterNetworkRequestMatchCallback(this);
134         }
135 
136         super.onPause();
137     }
138 
139     private final Handler mHandler = new Handler() {
140         @Override
141         public void handleMessage(Message msg) {
142             switch (msg.what) {
143                 case MESSAGE_STOP_SCAN_WIFI_LIST:
144                     removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
145                     stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.TIME_OUT);
146                     break;
147                 default:
148                     // Do nothing.
149                     break;
150             }
151         }
152     };
153 
stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type)154     protected void stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE type) {
155         dismissDialogs();
156 
157         // Throws error dialog.
158         final NetworkRequestErrorDialogFragment dialogFragment =
159                 NetworkRequestErrorDialogFragment.newInstance();
160         dialogFragment.setRejectCallback(mUserSelectionCallback);
161         final Bundle bundle = new Bundle();
162         bundle.putSerializable(NetworkRequestErrorDialogFragment.DIALOG_TYPE, type);
163         dialogFragment.setArguments(bundle);
164         dialogFragment.show(getSupportFragmentManager(), TAG);
165         mShowingErrorDialog = true;
166     }
167 
168     @Override
onUserSelectionCallbackRegistration( NetworkRequestUserSelectionCallback userSelectionCallback)169     public void onUserSelectionCallbackRegistration(
170         NetworkRequestUserSelectionCallback userSelectionCallback) {
171         if (mIsSpecifiedSsid) {
172             mUserSelectionCallback = userSelectionCallback;
173             return;
174         }
175 
176         mDialogFragment.onUserSelectionCallbackRegistration(userSelectionCallback);
177     }
178 
179     @Override
onAbort()180     public void onAbort() {
181         stopScanningAndPopErrorDialog(ERROR_DIALOG_TYPE.ABORT);
182     }
183 
184     @Override
onMatch(List<ScanResult> scanResults)185     public void onMatch(List<ScanResult> scanResults) {
186         if (mShowingErrorDialog) {
187             // Don't do anything since error dialog shows.
188             return;
189         }
190 
191         mHandler.removeMessages(MESSAGE_STOP_SCAN_WIFI_LIST);
192 
193         if (mIsSpecifiedSsid) {
194             // Prevent from throwing same dialog, because onMatch() will be called many times.
195             if (mMatchedConfig == null) {
196                 mMatchedConfig = WifiUtils.getWifiConfig(
197                     null /* accesspoint */, scanResults.get(0), null /* password */);
198                 showSingleSsidRequestDialog(
199                         WifiInfo.sanitizeSsid(mMatchedConfig.SSID), false /* isTryAgain */);
200             }
201             return;
202         }
203 
204         mDialogFragment.onMatch(scanResults);
205     }
206 
207     @Override
onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration)208     public void onUserSelectionConnectSuccess(WifiConfiguration wificonfiguration) {
209         if (!isFinishing()) {
210             Toast.makeText(this, R.string.network_connection_connect_successful, Toast.LENGTH_SHORT)
211                     .show();
212             setResult(RESULT_OK);
213             finish();
214         }
215     }
216 
217     @Override
onUserSelectionConnectFailure(WifiConfiguration wificonfiguration)218     public void onUserSelectionConnectFailure(WifiConfiguration wificonfiguration) {
219         if (!isFinishing()) {
220             Toast.makeText(this, R.string.network_connection_connect_failure, Toast.LENGTH_SHORT)
221                     .show();
222             setResult(RESULT_OK);
223             finish();
224         }
225     }
226 
227     // Called when user click "Connect" button. Called by
228     // {@code NetworkRequestSingleSsidDialogFragment}.
onClickConnectButton()229     public void onClickConnectButton() {
230         if (mUserSelectionCallback != null) {
231             mUserSelectionCallback.select(mMatchedConfig);
232             showProgressDialog(getString(R.string.network_connection_connecting_message));
233         }
234     }
235 
236     // Called when user click retry button. Called by {@link NetworkRequestErrorDialogFragment}.
onClickRescanButton()237     public void onClickRescanButton() {
238         // Sets time-out to stop scanning.
239         mHandler.sendEmptyMessageDelayed(MESSAGE_STOP_SCAN_WIFI_LIST, DELAY_TIME_STOP_SCAN_MS);
240 
241         mShowingErrorDialog = false;
242 
243         if (mIsSpecifiedSsid) {
244             mMatchedConfig = null;
245             showProgressDialog(getString(R.string.network_connection_searching_message));
246         } else {
247             mDialogFragment = NetworkRequestDialogFragment.newInstance();
248             mDialogFragment.show(getSupportFragmentManager(), TAG);
249         }
250     }
251 
252     // Called when user click cancel button.
onCancel()253     public void onCancel() {
254         dismissDialogs();
255 
256         if (mUserSelectionCallback != null) {
257             mUserSelectionCallback.reject();
258         }
259         finish();
260     }
261 }
262