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 static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG;
20 
21 import android.app.Activity;
22 import android.app.settings.SettingsEnums;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.net.wifi.WifiConfiguration;
26 import android.net.wifi.WifiManager;
27 import android.os.Bundle;
28 import android.os.UserManager;
29 import android.util.Log;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.view.WindowManager;
34 import android.widget.Button;
35 import android.widget.ImageButton;
36 import android.widget.TextView;
37 import android.widget.Toast;
38 
39 import androidx.annotation.VisibleForTesting;
40 
41 import com.android.settings.R;
42 import com.android.settings.core.InstrumentedFragment;
43 import com.android.settings.wifi.dpp.WifiDppQrCodeScannerFragment;
44 import com.android.settings.wifi.dpp.WifiDppUtils;
45 
46 /**
47  * A full screen UI component for users to edit and add a Wi-Fi network.
48  */
49 public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2,
50         View.OnClickListener {
51     private static final String TAG = "AddNetworkFragment";
52 
53     public static final String WIFI_CONFIG_KEY = "wifi_config_key";
54     @VisibleForTesting
55     final static int SUBMIT_BUTTON_ID = android.R.id.button1;
56     @VisibleForTesting
57     final static int CANCEL_BUTTON_ID = android.R.id.button2;
58     final static int SSID_SCANNER_BUTTON_ID = R.id.ssid_scanner_button;
59 
60     private static final int REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER = 0;
61 
62     private static final String EXTRA_SAVE_WHEN_SUBMIT = ":settings:save_when_submit";
63 
64     private WifiConfigController2 mUIController;
65     private Button mSubmitBtn;
66     private Button mCancelBtn;
67 
68     @Override
onCreate(Bundle savedInstanceState)69     public void onCreate(Bundle savedInstanceState) {
70         super.onCreate(savedInstanceState);
71         if (!isAddWifiConfigAllowed(getContext())) {
72             getActivity().finish();
73             return;
74         }
75     }
76 
77     @Override
getMetricsCategory()78     public int getMetricsCategory() {
79         return SettingsEnums.SETTINGS_WIFI_ADD_NETWORK;
80     }
81 
82     @Override
onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)83     public View onCreateView(LayoutInflater inflater, ViewGroup container,
84             Bundle savedInstanceState) {
85         final View rootView = inflater.inflate(R.layout.wifi_add_network_view, container, false);
86 
87         final Button neutral = rootView.findViewById(android.R.id.button3);
88         if (neutral != null) {
89             neutral.setVisibility(View.GONE);
90         }
91 
92         mSubmitBtn = rootView.findViewById(SUBMIT_BUTTON_ID);
93         mCancelBtn = rootView.findViewById(CANCEL_BUTTON_ID);
94         final ImageButton ssidScannerButton = rootView.findViewById(SSID_SCANNER_BUTTON_ID);
95         mSubmitBtn.setOnClickListener(this);
96         mCancelBtn.setOnClickListener(this);
97         ssidScannerButton.setOnClickListener(this);
98         mUIController = new WifiConfigController2(this, rootView, null, getMode());
99 
100         // Resize the layout when keyboard opens.
101         getActivity().getWindow().setSoftInputMode(
102                 WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
103 
104         return rootView;
105     }
106 
107     @Override
onResume()108     public void onResume() {
109         super.onResume();
110         mUIController.showSecurityFields(
111             /* refreshEapMethods */ false, /* refreshCertificates */ true);
112     }
113 
114     @Override
onViewStateRestored(Bundle savedInstanceState)115     public void onViewStateRestored(Bundle savedInstanceState) {
116         super.onViewStateRestored(savedInstanceState);
117         mUIController.updatePassword();
118     }
119 
120     @Override
onClick(View view)121     public void onClick(View view) {
122         if (view.getId() == SUBMIT_BUTTON_ID) {
123             handleSubmitAction();
124         } else if (view.getId() == CANCEL_BUTTON_ID) {
125             handleCancelAction();
126         } else if (view.getId() == SSID_SCANNER_BUTTON_ID) {
127             final TextView ssidEditText = getView().findViewById(R.id.ssid);
128             final String ssid = ssidEditText.getText().toString();
129 
130             // Launch QR code scanner to join a network.
131             startActivityForResult(
132                     WifiDppUtils.getEnrolleeQrCodeScannerIntent(view.getContext(), ssid),
133                     REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER);
134         }
135     }
136 
137     @Override
onActivityResult(int requestCode, int resultCode, Intent data)138     public void onActivityResult(int requestCode, int resultCode, Intent data) {
139         super.onActivityResult(requestCode, resultCode, data);
140         if (requestCode == REQUEST_CODE_WIFI_DPP_ENROLLEE_QR_CODE_SCANNER) {
141             if (resultCode != Activity.RESULT_OK) {
142                 return;
143             }
144 
145             final WifiConfiguration config = data.getParcelableExtra(
146                     WifiDppQrCodeScannerFragment.KEY_WIFI_CONFIGURATION);
147             successfullyFinish(config);
148         }
149     }
150 
151     @Override
getMode()152     public int getMode() {
153         return WifiConfigUiBase2.MODE_CONNECT;
154     }
155 
156     @Override
getController()157     public WifiConfigController2 getController() {
158         return mUIController;
159     }
160 
161     @Override
dispatchSubmit()162     public void dispatchSubmit() {
163         handleSubmitAction();
164     }
165 
166     @Override
setTitle(int id)167     public void setTitle(int id) {
168         getActivity().setTitle(id);
169     }
170 
171     @Override
setTitle(CharSequence title)172     public void setTitle(CharSequence title) {
173         getActivity().setTitle(title);
174     }
175 
176     @Override
setSubmitButton(CharSequence text)177     public void setSubmitButton(CharSequence text) {
178         mSubmitBtn.setText(text);
179     }
180 
181     @Override
setCancelButton(CharSequence text)182     public void setCancelButton(CharSequence text) {
183         mCancelBtn.setText(text);
184     }
185 
186     @Override
setForgetButton(CharSequence text)187     public void setForgetButton(CharSequence text) {
188         // AddNetwork doesn't need forget button.
189     }
190 
191     @Override
getSubmitButton()192     public Button getSubmitButton() {
193         return mSubmitBtn;
194     }
195 
196     @Override
getCancelButton()197     public Button getCancelButton() {
198         return mCancelBtn;
199     }
200 
201     @Override
getForgetButton()202     public Button getForgetButton() {
203         // AddNetwork doesn't need forget button.
204         return null;
205     }
206 
207     @VisibleForTesting
handleSubmitAction()208     void handleSubmitAction() {
209         successfullyFinish(mUIController.getConfig());
210     }
211 
successfullyFinish(WifiConfiguration config)212     private void successfullyFinish(WifiConfiguration config) {
213         Activity activity = getActivity();
214         boolean autoSave = activity.getIntent().getBooleanExtra(EXTRA_SAVE_WHEN_SUBMIT, false);
215         if (autoSave && config != null) {
216             WifiManager.ActionListener saveListener = new WifiManager.ActionListener() {
217                 @Override
218                 public void onSuccess() {
219                     if (activity != null && !activity.isFinishing()) {
220                         activity.setResult(Activity.RESULT_OK);
221                         activity.finish();
222                     }
223                 }
224 
225                 @Override
226                 public void onFailure(int reason) {
227                     if (activity != null && !activity.isFinishing()) {
228                         Toast.makeText(activity, R.string.wifi_failed_save_message,
229                                 Toast.LENGTH_SHORT).show();
230                         activity.finish();
231                     }
232                 }
233             };
234 
235             activity.getSystemService(WifiManager.class).save(config, saveListener);
236         } else {
237             Intent intent = new Intent();
238             intent.putExtra(WIFI_CONFIG_KEY, config);
239             activity.setResult(Activity.RESULT_OK, intent);
240             activity.finish();
241         }
242     }
243 
244     @VisibleForTesting
handleCancelAction()245     void handleCancelAction() {
246         final Activity activity = getActivity();
247         activity.setResult(Activity.RESULT_CANCELED);
248         activity.finish();
249     }
250 
251     @VisibleForTesting
isAddWifiConfigAllowed(Context context)252     static boolean isAddWifiConfigAllowed(Context context) {
253         UserManager userManager = context.getSystemService(UserManager.class);
254         if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) {
255             Log.e(TAG, "The user is not allowed to add Wi-Fi configuration.");
256             return false;
257         }
258         return true;
259     }
260 }
261