OSDN Git Service

Merge "Clean up ShadowUserManager"
[android-x86/packages-apps-Settings.git] / src / com / android / settings / wifi / dpp / WifiDppConfiguratorActivity.java
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.dpp;
18
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.app.settings.SettingsEnums;
22 import android.content.Intent;
23 import android.os.Bundle;
24 import android.provider.Settings;
25 import android.util.Log;
26
27 import androidx.annotation.VisibleForTesting;
28 import androidx.fragment.app.Fragment;
29 import androidx.fragment.app.FragmentManager;
30 import androidx.fragment.app.FragmentTransaction;
31
32 import com.android.settings.R;
33 import com.android.settings.core.InstrumentedActivity;
34
35 /**
36  * To provision "other" device with specified Wi-Fi network.
37  *
38  * Uses different intents to specify different provisioning ways.
39  *
40  * For intent action {@code ACTION_CONFIGURATOR_QR_CODE_SCANNER} and
41  * {@code android.settings.WIFI_DPP_CONFIGURATOR_QR_CODE_GENERATOR}, specify the Wi-Fi network to be
42  * provisioned in:
43  *
44  * {@code WifiDppUtils.EXTRA_WIFI_SECURITY}
45  * {@code WifiDppUtils.EXTRA_WIFI_SSID}
46  * {@code WifiDppUtils.EXTRA_WIFI_PRE_SHARED_KEY}
47  * {@code WifiDppUtils.EXTRA_WIFI_HIDDEN_SSID}
48  *
49  * For intent action {@link Settings#ACTION_PROCESS_WIFI_EASY_CONNECT_QR_CODE}, specify Wi-Fi (DPP)
50  * QR code in {@code WifiDppUtils.EXTRA_QR_CODE}
51  */
52 public class WifiDppConfiguratorActivity extends InstrumentedActivity implements
53         WifiNetworkConfig.Retriever,
54         WifiDppQrCodeGeneratorFragment.OnQrCodeGeneratorFragmentAddButtonClickedListener,
55         WifiDppQrCodeScannerFragment.OnScanWifiDppSuccessListener,
56         WifiDppQrCodeScannerFragment.OnScanZxingWifiFormatSuccessListener,
57         WifiDppAddDeviceFragment.OnClickChooseDifferentNetworkListener,
58         WifiNetworkListFragment.OnChooseNetworkListener {
59
60     private static final String TAG = "WifiDppConfiguratorActivity";
61
62     public static final String ACTION_CONFIGURATOR_QR_CODE_SCANNER =
63             "android.settings.WIFI_DPP_CONFIGURATOR_QR_CODE_SCANNER";
64     public static final String ACTION_CONFIGURATOR_QR_CODE_GENERATOR =
65             "android.settings.WIFI_DPP_CONFIGURATOR_QR_CODE_GENERATOR";
66
67     // Key for Bundle usage
68     private static final String KEY_QR_CODE = "key_qr_code";
69     private static final String KEY_WIFI_SECURITY = "key_wifi_security";
70     private static final String KEY_WIFI_SSID = "key_wifi_ssid";
71     private static final String KEY_WIFI_PRESHARED_KEY = "key_wifi_preshared_key";
72     private static final String KEY_WIFI_HIDDEN_SSID = "key_wifi_hidden_ssid";
73     private static final String KEY_WIFI_NETWORK_ID = "key_wifi_network_id";
74
75     private FragmentManager mFragmentManager;
76
77     /** The Wi-Fi network which will be configured */
78     private WifiNetworkConfig mWifiNetworkConfig;
79
80     /** The Wi-Fi DPP QR code from intent ACTION_PROCESS_WIFI_EASY_CONNECT_QR_CODE */
81     private WifiQrCode mWifiDppQrCode;
82     /** Secret extra that allows fake networks to show in UI for testing purposes */
83     private boolean mIsTest;
84
85     @Override
86     public int getMetricsCategory() {
87         return SettingsEnums.SETTINGS_WIFI_DPP_CONFIGURATOR;
88     }
89
90     @Override
91     protected void onCreate(Bundle savedInstanceState) {
92         super.onCreate(savedInstanceState);
93
94         if (savedInstanceState != null) {
95             String qrCode = savedInstanceState.getString(KEY_QR_CODE);
96
97             mWifiDppQrCode = getValidWifiDppQrCodeOrNull(qrCode);
98
99             String security = savedInstanceState.getString(KEY_WIFI_SECURITY);
100             String ssid = savedInstanceState.getString(KEY_WIFI_SSID);
101             String preSharedKey = savedInstanceState.getString(KEY_WIFI_PRESHARED_KEY);
102             boolean hiddenSsid = savedInstanceState.getBoolean(KEY_WIFI_HIDDEN_SSID);
103             int networkId = savedInstanceState.getInt(KEY_WIFI_NETWORK_ID);
104
105             mWifiNetworkConfig = WifiNetworkConfig.getValidConfigOrNull(security, ssid,
106                     preSharedKey, hiddenSsid, networkId);
107         }
108
109         setContentView(R.layout.wifi_dpp_activity);
110         mFragmentManager = getSupportFragmentManager();
111
112         handleIntent(getIntent());
113
114         ActionBar actionBar = getActionBar();
115         if (actionBar != null) {
116             actionBar.setElevation(0);
117             actionBar.setDisplayShowTitleEnabled(false);
118         }
119     }
120
121     private void handleIntent(Intent intent) {
122         boolean cancelActivity = false;
123         WifiNetworkConfig config;
124         switch (intent.getAction()) {
125             case ACTION_CONFIGURATOR_QR_CODE_SCANNER:
126                 config = WifiNetworkConfig.getValidConfigOrNull(intent);
127                 if (config == null) {
128                     cancelActivity = true;
129                 } else {
130                     mWifiNetworkConfig = config;
131                     showQrCodeScannerFragment(/* addToBackStack= */ false);
132                 }
133                 break;
134             case ACTION_CONFIGURATOR_QR_CODE_GENERATOR:
135                 config = WifiNetworkConfig.getValidConfigOrNull(intent);
136                 if (config == null) {
137                     cancelActivity = true;
138                 } else {
139                     mWifiNetworkConfig = config;
140                     showQrCodeGeneratorFragment();
141                 }
142                 break;
143             case Settings.ACTION_PROCESS_WIFI_EASY_CONNECT_QR_CODE:
144                 String qrCode = intent.getStringExtra(Settings.EXTRA_QR_CODE);
145                 mIsTest = intent.getBooleanExtra(WifiDppUtils.EXTRA_TEST, false);
146                 mWifiDppQrCode = getValidWifiDppQrCodeOrNull(qrCode);
147                 final boolean isDppSupported = WifiDppUtils.isWifiDppEnabled(this);
148                 if (!isDppSupported) {
149                     Log.d(TAG, "Device doesn't support Wifi DPP");
150                 }
151                 if (mWifiDppQrCode == null || !isDppSupported) {
152                     cancelActivity = true;
153                 } else {
154                     showChooseSavedWifiNetworkFragment(/* addToBackStack */ false);
155                 }
156                 break;
157             default:
158                 cancelActivity = true;
159                 Log.e(TAG, "Launch with an invalid action");
160         }
161
162         if (cancelActivity) {
163             setResult(Activity.RESULT_CANCELED);
164             finish();
165         }
166     }
167
168     private void showQrCodeScannerFragment(boolean addToBackStack) {
169         WifiDppQrCodeScannerFragment fragment =
170                 (WifiDppQrCodeScannerFragment) mFragmentManager.findFragmentByTag(
171                         WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
172         // Avoid to replace the same fragment during configuration change
173         if (fragment != null && fragment.isVisible()) {
174             return;
175         }
176
177         if (fragment == null) {
178             fragment = new WifiDppQrCodeScannerFragment();
179         }
180         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
181
182         fragmentTransaction.replace(R.id.fragment_container, fragment,
183                 WifiDppUtils.TAG_FRAGMENT_QR_CODE_SCANNER);
184         if (addToBackStack) {
185             fragmentTransaction.addToBackStack(/* name */ null);
186         }
187         fragmentTransaction.commit();
188     }
189
190     private void showQrCodeGeneratorFragment() {
191         WifiDppQrCodeGeneratorFragment fragment =
192                 (WifiDppQrCodeGeneratorFragment) mFragmentManager.findFragmentByTag(
193                         WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
194         // Avoid to replace the same fragment during configuration change
195         if (fragment != null && fragment.isVisible()) {
196             return;
197         }
198
199         fragment = new WifiDppQrCodeGeneratorFragment();
200         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
201
202         fragmentTransaction.replace(R.id.fragment_container, fragment,
203                 WifiDppUtils.TAG_FRAGMENT_QR_CODE_GENERATOR);
204         fragmentTransaction.commit();
205     }
206
207     private void showChooseSavedWifiNetworkFragment(boolean addToBackStack) {
208         WifiDppChooseSavedWifiNetworkFragment fragment =
209                 (WifiDppChooseSavedWifiNetworkFragment) mFragmentManager.findFragmentByTag(
210                         WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
211         // Avoid to replace the same fragment during configuration change
212         if (fragment != null && fragment.isVisible()) {
213             return;
214         }
215
216         if (fragment == null) {
217             fragment = new WifiDppChooseSavedWifiNetworkFragment();
218             if (mIsTest) {
219                 Bundle bundle = new Bundle();
220                 bundle.putBoolean(WifiDppUtils.EXTRA_TEST, true);
221                 fragment.setArguments(bundle);
222             }
223         }
224         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
225
226         fragmentTransaction.replace(R.id.fragment_container, fragment,
227                 WifiDppUtils.TAG_FRAGMENT_CHOOSE_SAVED_WIFI_NETWORK);
228         if (addToBackStack) {
229             fragmentTransaction.addToBackStack(/* name */ null);
230         }
231         fragmentTransaction.commit();
232     }
233
234     private void showAddDeviceFragment(boolean addToBackStack) {
235         WifiDppAddDeviceFragment fragment =
236                 (WifiDppAddDeviceFragment) mFragmentManager.findFragmentByTag(
237                         WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE);
238
239         // Avoid to replace the same fragment during configuration change
240         if (mFragmentManager.findFragmentByTag(
241                 WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE) != null) {
242             return;
243         }
244
245         if (fragment == null) {
246             fragment = new WifiDppAddDeviceFragment();
247         }
248         final FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
249
250         fragmentTransaction.replace(R.id.fragment_container, fragment,
251                 WifiDppUtils.TAG_FRAGMENT_ADD_DEVICE);
252         if (addToBackStack) {
253             fragmentTransaction.addToBackStack(/* name */ null);
254         }
255         fragmentTransaction.commit();
256     }
257
258     private WifiQrCode getValidWifiDppQrCodeOrNull(String qrCode) {
259         WifiQrCode wifiQrCode;
260         try {
261             wifiQrCode = new WifiQrCode(qrCode);
262         } catch(IllegalArgumentException e) {
263             return null;
264         }
265
266         if (WifiQrCode.SCHEME_DPP.equals(wifiQrCode.getScheme())) {
267             return wifiQrCode;
268         }
269
270         return null;
271     }
272
273     @Override
274     public WifiNetworkConfig getWifiNetworkConfig() {
275         return mWifiNetworkConfig;
276     }
277
278     public WifiQrCode getWifiDppQrCode() {
279         return mWifiDppQrCode;
280     }
281
282     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
283     protected boolean setWifiNetworkConfig(WifiNetworkConfig config) {
284         if(!WifiNetworkConfig.isValidConfig(config)) {
285             return false;
286         } else {
287             mWifiNetworkConfig = new WifiNetworkConfig(config);
288             return true;
289         }
290     }
291
292     @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
293     protected boolean setWifiDppQrCode(WifiQrCode wifiQrCode) {
294         if (wifiQrCode == null) {
295             return false;
296         }
297
298         if (!WifiQrCode.SCHEME_DPP.equals(wifiQrCode.getScheme())) {
299             return false;
300         }
301
302         mWifiDppQrCode = new WifiQrCode(wifiQrCode.getQrCode());
303         return true;
304     }
305
306     @Override
307     public boolean onNavigateUp() {
308         Fragment fragment = mFragmentManager.findFragmentById(R.id.fragment_container);
309         if (fragment instanceof WifiDppQrCodeGeneratorFragment) {
310             setResult(Activity.RESULT_CANCELED);
311             finish();
312             return true;
313         } else if (fragment instanceof WifiDppQrCodeScannerFragment) {
314             mFragmentManager.popBackStackImmediate();
315         }
316
317         return false;
318     }
319
320     @Override
321     public void onQrCodeGeneratorFragmentAddButtonClicked() {
322         showQrCodeScannerFragment(/* addToBackStack */ true);
323     }
324
325     @Override
326     public void onScanWifiDppSuccess(WifiQrCode wifiQrCode) {
327         mWifiDppQrCode = wifiQrCode;
328
329         showAddDeviceFragment(/* addToBackStack */ true);
330     }
331
332     @Override
333     public void onScanZxingWifiFormatSuccess(WifiNetworkConfig wifiNetworkConfig) {
334         // Do nothing, it's impossible to be a configurator without a Wi-Fi DPP QR code
335     }
336
337     @Override
338     public void onClickChooseDifferentNetwork() {
339         showChooseSavedWifiNetworkFragment(/* addToBackStack */ true);
340     }
341
342     @Override
343     public void onSaveInstanceState(Bundle outState) {
344         if (mWifiDppQrCode != null) {
345             outState.putString(KEY_QR_CODE, mWifiDppQrCode.getQrCode());
346         }
347
348         if (mWifiNetworkConfig != null) {
349             outState.putString(KEY_WIFI_SECURITY, mWifiNetworkConfig.getSecurity());
350             outState.putString(KEY_WIFI_SSID, mWifiNetworkConfig.getSsid());
351             outState.putString(KEY_WIFI_PRESHARED_KEY, mWifiNetworkConfig.getPreSharedKey());
352             outState.putBoolean(KEY_WIFI_HIDDEN_SSID, mWifiNetworkConfig.getHiddenSsid());
353             outState.putInt(KEY_WIFI_NETWORK_ID, mWifiNetworkConfig.getNetworkId());
354         }
355
356         super.onSaveInstanceState(outState);
357     }
358
359     @Override
360     public void onChooseNetwork(WifiNetworkConfig wifiNetworkConfig) {
361         mWifiNetworkConfig = new WifiNetworkConfig(wifiNetworkConfig);
362
363         showAddDeviceFragment(/* addToBackStack */ true);
364     }
365 }