• 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.util.Log;
23 import android.view.View;
24 import android.widget.AdapterView;
25 import android.widget.TextView;
26 import android.widget.Toast;
27 
28 import com.android.car.settings.R;
29 import com.android.car.settings.common.EditTextLineItem;
30 import com.android.car.settings.common.ListSettingsFragment;
31 import com.android.car.settings.common.PasswordLineItem;
32 import com.android.car.settings.common.SpinnerLineItem;
33 import com.android.car.settings.common.TypedPagedListAdapter;
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 String TAG = "AddWifiFragment";
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 private AccessPoint mAccessPoint;
54     @Nullable private SpinnerLineItem<AccessPointSecurity> mSpinnerLineItem;
55     private WifiManager mWifiManager;
56     private TextView mAddWifiButton;
57     private final WifiManager.ActionListener mConnectionListener =
58             new WifiManager.ActionListener() {
59         @Override
60         public void onSuccess() {
61         }
62 
63         @Override
64         public void onFailure(int reason) {
65             Toast.makeText(getContext(),
66                     R.string.wifi_failed_connect_message,
67                     Toast.LENGTH_SHORT).show();
68         }
69     };
70     private EditTextLineItem mWifiNameInput;
71     private EditTextLineItem mWifiPasswordInput;
72 
73     private int mSelectedPosition = AccessPointSecurity.SECURITY_NONE_POSITION;
74 
getInstance(AccessPoint accessPoint)75     public static AddWifiFragment getInstance(AccessPoint accessPoint) {
76         AddWifiFragment addWifiFragment = new AddWifiFragment();
77         Bundle bundle = ListSettingsFragment.getBundle();
78         bundle.putInt(EXTRA_TITLE_ID, R.string.wifi_setup_add_network);
79         bundle.putInt(EXTRA_ACTION_BAR_LAYOUT, R.layout.action_bar_with_button);
80         Bundle accessPointState = new Bundle();
81         if (accessPoint != null) {
82             accessPoint.saveWifiState(accessPointState);
83             bundle.putBundle(EXTRA_AP_STATE, accessPointState);
84         }
85         addWifiFragment.setArguments(bundle);
86         return addWifiFragment;
87     }
88 
89     @Override
onCreate(Bundle savedInstanceState)90     public void onCreate(Bundle savedInstanceState) {
91         super.onCreate(savedInstanceState);
92         if (getArguments().keySet().contains(EXTRA_AP_STATE)) {
93             mAccessPoint = new AccessPoint(getContext(), getArguments().getBundle(EXTRA_AP_STATE));
94         }
95         mWifiManager = getContext().getSystemService(WifiManager.class);
96     }
97 
98     @Override
onActivityCreated(Bundle savedInstanceState)99     public void onActivityCreated(Bundle savedInstanceState) {
100         super.onActivityCreated(savedInstanceState);
101 
102         mAddWifiButton = getActivity().findViewById(R.id.action_button1);
103         mAddWifiButton.setText(R.string.wifi_setup_connect);
104         mAddWifiButton.setOnClickListener(v -> {
105             connectToAccessPoint();
106             mFragmentController.goBack();
107         });
108         mAddWifiButton.setEnabled(mAccessPoint != null) ;
109     }
110 
111     @Override
getLineItems()112     public ArrayList<TypedPagedListAdapter.LineItem> getLineItems() {
113         ArrayList<TypedPagedListAdapter.LineItem> lineItems = new ArrayList<>();
114         if (mAccessPoint != null) {
115             mWifiNameInput = new EditTextLineItem(
116                     getContext().getText(R.string.wifi_ssid), mAccessPoint.getSsid());
117             mWifiNameInput.setTextType(EditTextLineItem.TextType.NONE);
118         } else {
119             mWifiNameInput = new EditTextLineItem(
120                     getContext().getText(R.string.wifi_ssid));
121             mWifiNameInput.setTextType(EditTextLineItem.TextType.TEXT);
122             mWifiNameInput.setTextChangeListener(s ->
123                     mAddWifiButton.setEnabled(VALID_SSID_PATTERN.matcher(s).matches()));
124         }
125         lineItems.add(mWifiNameInput);
126 
127         if (mAccessPoint == null) {
128             List<AccessPointSecurity> securities =
129                     AccessPointSecurity.getSecurityTypes(getContext());
130             mSpinnerLineItem = new SpinnerLineItem<>(
131                     getContext(),
132                     this,
133                     securities,
134                     getContext().getText(R.string.wifi_security),
135                     mSelectedPosition);
136             lineItems.add(mSpinnerLineItem);
137         }
138 
139         if (mAccessPoint!= null
140                 || mSelectedPosition != AccessPointSecurity.SECURITY_NONE_POSITION) {
141             mWifiPasswordInput = new PasswordLineItem(getContext().getText(R.string.wifi_password));
142             lineItems.add(mWifiPasswordInput);
143         }
144         return lineItems;
145     }
146 
147     @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)148     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
149         if (position == mSelectedPosition) {
150             return;
151         }
152         mSelectedPosition = position;
153         mPagedListAdapter.updateList(getLineItems());
154     }
155 
156     @Override
onNothingSelected(AdapterView<?> parent)157     public void onNothingSelected(AdapterView<?> parent) {
158     }
159 
connectToAccessPoint()160     private void connectToAccessPoint() {
161         WifiConfiguration wifiConfig = new WifiConfiguration();
162         wifiConfig.SSID = String.format("\"%s\"", getSsId());
163         wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
164         wifiConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
165         wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
166         wifiConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
167         wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
168         wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
169         int security;
170         if (mAccessPoint == null) {
171             security = mSpinnerLineItem.getItem(mSelectedPosition).getSecurityType();
172             wifiConfig.hiddenSSID = true;
173         } else {
174             security = mAccessPoint.getSecurity();
175         }
176         switch (security) {
177             case AccessPoint.SECURITY_NONE:
178                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
179                 wifiConfig.allowedAuthAlgorithms.clear();
180                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
181                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
182                 break;
183             case AccessPoint.SECURITY_WEP:
184                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
185                 wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
186                 wifiConfig.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
187                 String password = mWifiPasswordInput.getInput();
188                 wifiConfig.wepKeys[0] = isHexString(password) ? password
189                         : "\"" + password + "\"";
190                 wifiConfig.wepTxKeyIndex = 0;
191                 break;
192             case AccessPoint.SECURITY_PSK:
193             case AccessPoint.SECURITY_EAP:
194                 wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
195                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
196                 wifiConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
197                 wifiConfig.preSharedKey = String.format(
198                         "\"%s\"", mWifiPasswordInput.getInput());
199                 break;
200             default:
201                 Log.w(TAG, "invalid security type: " + security);
202                 break;
203         }
204         int netId = mWifiManager.addNetwork(wifiConfig);
205         if (netId == -1) {
206             Toast.makeText(getContext(),
207                     R.string.wifi_failed_connect_message,
208                     Toast.LENGTH_SHORT).show();
209         } else {
210             mWifiManager.enableNetwork(netId, true);
211         }
212     }
213 
isHexString(String password)214     private boolean isHexString(String password) {
215         return HEX_PATTERN.matcher(password).matches();
216     }
217 
218     // TODO: handle null case, show warning message etc.
getSsId()219     private String getSsId() {
220         if (mAccessPoint == null) {
221             return mWifiNameInput.getInput();
222         } else {
223             return mAccessPoint.getSsid().toString();
224         }
225     }
226 }
227