• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.car.settings.wifi;
17 
18 import android.net.wifi.WifiConfiguration;
19 import android.net.wifi.WifiManager;
20 import android.os.Bundle;
21 import android.support.annotation.Nullable;
22 import android.view.View;
23 import android.widget.AdapterView;
24 import android.widget.Button;
25 import android.widget.Toast;
26 
27 import com.android.car.list.EditTextLineItem;
28 import com.android.car.list.PasswordLineItem;
29 import com.android.car.list.SpinnerLineItem;
30 import com.android.car.list.TypedPagedListAdapter;
31 import com.android.car.settings.R;
32 import com.android.car.settings.common.ListSettingsFragment;
33 import com.android.car.settings.common.Logger;
34 import com.android.settingslib.wifi.AccessPoint;
35 
36 import java.util.ArrayList;
37 import java.util.List;
38 import java.util.regex.Pattern;
39 
40 /**
41  * Adds a wifi network, the network can be public or private. If ADD_NETWORK_MODE is not specified
42  * in the intent, then it needs to contain AccessPoint information, which is be use that to
43  * render UI, e.g. show SSID etc.
44  */
45 public class AddWifiFragment extends ListSettingsFragment implements
46         AdapterView.OnItemSelectedListener {
47     public static final String EXTRA_AP_STATE = "extra_ap_state";
48 
49     private static final Logger LOG = new Logger(AddWifiFragment.class);
50     private static final Pattern HEX_PATTERN = Pattern.compile("^[0-9A-F]+$");
51     private static final Pattern VALID_SSID_PATTERN =
52             Pattern.compile("^[A-Za-z]+[\\w\\-\\:\\.]*$");
53     @Nullable
54     private AccessPoint mAccessPoint;
55     @Nullable
56     private SpinnerLineItem<AccessPointSecurity> mSpinnerLineItem;
57     private WifiManager mWifiManager;
58     private Button mAddWifiButton;
59     private final WifiManager.ActionListener mConnectionListener =
60             new WifiManager.ActionListener() {
61                 @Override
62                 public void onSuccess() {
63                 }
64 
65                 @Override
66                 public void onFailure(int reason) {
67                     Toast.makeText(getContext(),
68                             R.string.wifi_failed_connect_message,
69                             Toast.LENGTH_SHORT).show();
70                 }
71             };
72     private EditTextLineItem mWifiNameInput;
73     private EditTextLineItem mWifiPasswordInput;
74 
75     private int mSelectedPosition = AccessPointSecurity.SECURITY_NONE_POSITION;
76 
getInstance(AccessPoint accessPoint)77     public static AddWifiFragment getInstance(AccessPoint accessPoint) {
78         AddWifiFragment addWifiFragment = new AddWifiFragment();
79         Bundle bundle = ListSettingsFragment.getBundle();
80         bundle.putInt(EXTRA_TITLE_ID, R.string.wifi_setup_add_network);
81         bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar_with_button);
82         Bundle accessPointState = new Bundle();
83         if (accessPoint != null) {
84             accessPoint.saveWifiState(accessPointState);
85             bundle.putBundle(EXTRA_AP_STATE, accessPointState);
86         }
87         addWifiFragment.setArguments(bundle);
88         return addWifiFragment;
89     }
90 
91     @Override
onCreate(Bundle savedInstanceState)92     public void onCreate(Bundle savedInstanceState) {
93         super.onCreate(savedInstanceState);
94         if (getArguments().keySet().contains(EXTRA_AP_STATE)) {
95             mAccessPoint = new AccessPoint(getContext(), getArguments().getBundle(EXTRA_AP_STATE));
96         }
97         mWifiManager = getContext().getSystemService(WifiManager.class);
98     }
99 
100     @Override
onActivityCreated(Bundle savedInstanceState)101     public void onActivityCreated(Bundle savedInstanceState) {
102         super.onActivityCreated(savedInstanceState);
103 
104         mAddWifiButton = getActivity().findViewById(R.id.action_button1);
105         mAddWifiButton.setText(R.string.wifi_setup_connect);
106         mAddWifiButton.setOnClickListener(v -> {
107             connectToAccessPoint();
108             getFragmentController().goBack();
109         });
110         mAddWifiButton.setEnabled(mAccessPoint != null);
111     }
112 
113     @Override
getLineItems()114     public ArrayList<TypedPagedListAdapter.LineItem> getLineItems() {
115         ArrayList<TypedPagedListAdapter.LineItem> lineItems = new ArrayList<>();
116         if (mAccessPoint != null) {
117             mWifiNameInput = new EditTextLineItem(
118                     getContext().getText(R.string.wifi_ssid), mAccessPoint.getSsid());
119             mWifiNameInput.setTextType(EditTextLineItem.TextType.NONE);
120         } else {
121             mWifiNameInput = new EditTextLineItem(
122                     getContext().getText(R.string.wifi_ssid));
123             mWifiNameInput.setTextType(EditTextLineItem.TextType.TEXT);
124             mWifiNameInput.setTextChangeListener(s ->
125                     mAddWifiButton.setEnabled(VALID_SSID_PATTERN.matcher(s).matches()));
126         }
127         lineItems.add(mWifiNameInput);
128 
129         if (mAccessPoint == null) {
130             List<AccessPointSecurity> securities =
131                     AccessPointSecurity.getSecurityTypes(getContext());
132             mSpinnerLineItem = new SpinnerLineItem<>(
133                     getContext(),
134                     this,
135                     securities,
136                     getContext().getText(R.string.wifi_security),
137                     mSelectedPosition);
138             lineItems.add(mSpinnerLineItem);
139         }
140 
141         if (mAccessPoint != null
142                 || mSelectedPosition != AccessPointSecurity.SECURITY_NONE_POSITION) {
143             mWifiPasswordInput = new PasswordLineItem(getContext().getText(R.string.wifi_password));
144             lineItems.add(mWifiPasswordInput);
145         }
146         return lineItems;
147     }
148 
149     @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)150     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
151         if (position == mSelectedPosition) {
152             return;
153         }
154         mSelectedPosition = position;
155         mPagedListAdapter.setList(getLineItems());
156     }
157 
158     @Override
onNothingSelected(AdapterView<?> parent)159     public void onNothingSelected(AdapterView<?> parent) {
160     }
161 
connectToAccessPoint()162     private void connectToAccessPoint() {
163         WifiConfiguration wifiConfig = new WifiConfiguration();
164         wifiConfig.SSID = String.format("\"%s\"", getSsId());
165         wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
166         wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
167         wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
168         wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
169         wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
170         wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
171         int security;
172         if (mAccessPoint == null) {
173             security = mSpinnerLineItem.getItem(mSelectedPosition).getSecurityType();
174             wifiConfig.hiddenSSID = true;
175         } else {
176             security = mAccessPoint.getSecurity();
177         }
178         switch (security) {
179             case AccessPoint.SECURITY_NONE:
180                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
181                 wifiConfig.allowedAuthAlgorithms.clear();
182                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
183                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
184                 break;
185             case AccessPoint.SECURITY_WEP:
186                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
187                 wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
188                 wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
189                 String password = mWifiPasswordInput.getInput();
190                 wifiConfig.wepKeys[0] = isHexString(password) ? password
191                         : "\"" + password + "\"";
192                 wifiConfig.wepTxKeyIndex = 0;
193                 break;
194             case AccessPoint.SECURITY_PSK:
195             case AccessPoint.SECURITY_EAP:
196                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
197                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
198                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
199                 wifiConfig.preSharedKey = String.format(
200                         "\"%s\"", mWifiPasswordInput.getInput());
201                 break;
202             default:
203                 LOG.w("invalid security type: " + security);
204                 break;
205         }
206         int netId = mWifiManager.addNetwork(wifiConfig);
207         if (netId == -1) {
208             Toast.makeText(getContext(),
209                     R.string.wifi_failed_connect_message,
210                     Toast.LENGTH_SHORT).show();
211         } else {
212             mWifiManager.enableNetwork(netId, true);
213         }
214     }
215 
isHexString(String password)216     private boolean isHexString(String password) {
217         return HEX_PATTERN.matcher(password).matches();
218     }
219 
220     // TODO: handle null case, show warning message etc.
getSsId()221     private String getSsId() {
222         if (mAccessPoint == null) {
223             return mWifiNameInput.getInput();
224         } else {
225             return mAccessPoint.getSsid().toString();
226         }
227     }
228 }
229