Added README.txt and GPL Header to Source Files
[DHBWCampusApp.git] / app / src / main / java / de / dhbwloe / campusapp / fragments / WifiSettings.java
1 /* WifiSettings.java
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 3 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 package de.dhbwloe.campusapp.fragments;
17 import android.annotation.TargetApi;
18 import android.app.ActionBar;
19 import android.app.Activity;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.content.res.Resources;
25 import android.net.ConnectivityManager;
26 import android.net.NetworkInfo;
27 import android.net.wifi.ScanResult;
28 import android.net.wifi.SupplicantState;
29 import android.net.wifi.WifiConfiguration;
30 import android.net.wifi.WifiEnterpriseConfig;
31 import android.net.wifi.WifiInfo;
32 import android.net.wifi.WifiManager;
33 import android.os.Build;
34 import android.os.Bundle;
35 import android.support.design.widget.TabLayout;
36 import android.support.v4.app.Fragment;
37 import android.util.Base64;
38 import android.util.Log;
39 import android.view.LayoutInflater;
40 import android.view.View;
41 import android.view.ViewGroup;
42 import android.widget.Button;
43 import android.widget.EditText;
44 import android.widget.RelativeLayout;
45 import android.widget.TableRow;
46 import android.widget.TextView;
47
48 import java.io.ByteArrayInputStream;
49 import java.io.IOException;
50 import java.io.StringReader;
51 import java.lang.reflect.Field;
52 import java.security.cert.CertificateException;
53 import java.security.cert.CertificateFactory;
54 import java.security.cert.X509Certificate;
55 import java.util.List;
56
57 import de.dhbwloe.campusapp.CampusAppContext;
58 import de.dhbwloe.campusapp.CampusAppFragment;
59 import de.dhbwloe.campusapp.R;
60 import de.dhbwloe.campusapp.search.SearchIndices;
61 import de.dhbwloe.campusapp.wifi.WifiConfigurationManager;
62 import de.dhbwloe.campusapp.wifi.WifiNetworkSettings;
63
64 /**
65  * A simple {@link Fragment} subclass.
66  */
67 public class WifiSettings extends CampusAppFragment {
68     /* implement this for search results ;) */
69     public static SearchIndices[] GetSearchIndices() {
70         return new SearchIndices[]{
71                 new SearchIndices("WifiSettings", true) {{
72                     setUpdateTime(1);
73                     setTarget("#WifiSettings");
74                     setTitle(R.string.search_wifi_title);
75                     setDescription(R.string.search_wifi_description);
76                     addKeyWord(R.string.search_wifi_keywords);
77                 }},
78         };
79     }
80
81     private View view;
82     private TabLayout tablayout;
83     private WifiNetworkSettings[] wifiPresets;
84     private WifiManager wifiManager;
85     private WifiConfigurationManager wifiConfigManager;
86     private ConnectivityManager connectivityManager;
87     private int selectedNetworkIndex = 0;
88     private boolean networkScanned = false;
89     private BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
90         @Override
91         public void onReceive(Context arg0, Intent intent) {
92             String action  = intent.getAction();
93             if(action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)){
94                 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
95                 SupplicantState wifiState = ((SupplicantState) intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE));
96
97                 wifiConfigManager.updateWifiState(wifiInfo, wifiState);
98             }
99
100             updateWifiState();
101         }
102     };
103     private BroadcastReceiver wifiScanReceiver = new BroadcastReceiver() {
104         @Override
105         public void onReceive(Context arg0, Intent arg1) {
106             updateWifiScanState();
107         }
108     };
109
110
111
112     @Override
113     public void onCreate(Bundle savedInstanceState) {
114         super.onCreate(savedInstanceState);
115
116         wifiPresets = WifiNetworkSettings.LoadNetworkSettingPresets(AppContext);
117
118         wifiManager = (WifiManager)AppContext.getMainActivity().getSystemService(AppContext.getMainActivity().WIFI_SERVICE);
119         connectivityManager = (ConnectivityManager) AppContext.getMainActivity().getSystemService(Activity.CONNECTIVITY_SERVICE);
120
121         wifiConfigManager = new WifiConfigurationManager(wifiManager, this);
122     }
123
124     public String trimWifiSSID(String ssid) {
125         if(ssid == null)
126             return null;
127         if(ssid.matches("^\"(.*)\"$")) {
128             ssid = ssid.substring(1, ssid.length()-1);
129         }
130
131         return ssid;
132     }
133
134     private void updateSelectedNetworkInformation() {
135         if(view == null)
136             return;
137         if(selectedNetworkIndex >= wifiPresets.length)
138             return;
139
140         WifiNetworkSettings settings = wifiPresets[selectedNetworkIndex];
141         TextView ssidInfoView = (TextView) view.findViewById(R.id.ssidInfo);
142         TextView securityInfoView = (TextView) view.findViewById(R.id.securityInfo);
143         TextView eapInfoView = (TextView) view.findViewById(R.id.eapInfo);
144         TextView phase2InfoView = (TextView) view.findViewById(R.id.phase2Info);
145         TextView cacertInfoView = (TextView) view.findViewById(R.id.cacertInfo);
146
147         TableRow eapInfoRow = (TableRow) view.findViewById(R.id.eapInfoRow);
148         TableRow phase2InfoRow = (TableRow) view.findViewById(R.id.phase2InfoRow);
149         TableRow cacertInfoRow = (TableRow) view.findViewById(R.id.cacertInfoRow);
150         TableRow pskInfoRow = (TableRow) view.findViewById(R.id.pskInfoRow);
151
152         RelativeLayout insecureNetWarning = (RelativeLayout) view.findViewById(R.id.insecureNetWarning);
153
154
155         ssidInfoView.setText(settings.getSSID());
156
157         eapInfoRow.setVisibility(View.GONE);
158         phase2InfoRow.setVisibility(View.GONE);
159         cacertInfoRow.setVisibility(View.GONE);
160         pskInfoRow.setVisibility(View.GONE);
161         insecureNetWarning.setVisibility(View.GONE);
162
163         switch(settings.getAuthType()) {
164             case WIFI_AUTHTYPE_NONE:
165                 securityInfoView.setText(R.string.wifiopts_security_open);
166
167                 insecureNetWarning.setVisibility(View.VISIBLE);
168                 break;
169             case WIFI_AUTHTYPE_WEP:
170                 securityInfoView.setText(R.string.wifiopts_security_wep);
171                 insecureNetWarning.setVisibility(View.VISIBLE);
172                 // unsupported!
173                 break;
174             case WIFI_AUTHTYPE_WPA:
175                 securityInfoView.setText(R.string.wifiopts_security_wpa);
176
177                 pskInfoRow.setVisibility(View.VISIBLE);
178                 break;
179             case WIFI_AUTHTYPE_WPA_ENTERPRISE:
180                 securityInfoView.setText(R.string.wifiopts_security_wpa_enterprise);
181
182                 eapInfoRow.setVisibility(View.VISIBLE);
183                 phase2InfoRow.setVisibility(View.VISIBLE);
184                 cacertInfoRow.setVisibility(View.VISIBLE);
185                 break;
186         }
187
188         if(settings.getAuthType() == WifiNetworkSettings.WifiNetworkAuthenticationTypes.WIFI_AUTHTYPE_WPA_ENTERPRISE) {
189             int eapStringId = 0;
190             switch(settings.getEapMethod()) {
191                 case WifiEnterpriseConfig.Eap.PEAP:
192                     eapStringId = R.string.wifiopts_eap_peap;
193                     break;
194                 case WifiEnterpriseConfig.Eap.TLS:
195                     eapStringId = R.string.wifiopts_eap_tls;
196                     break;
197                 case WifiEnterpriseConfig.Eap.TTLS:
198                     eapStringId = R.string.wifiopts_eap_ttls;
199                     break;
200                 case WifiEnterpriseConfig.Eap.PWD:
201                     eapStringId = R.string.wifiopts_eap_pwd;
202                     break;
203             }
204             if(eapStringId > 0)
205                 eapInfoView.setText(eapStringId);
206             else
207                 eapInfoView.setText("");
208
209             int phase2StringId = 0;
210             switch(settings.getPhase2Method()) {
211                 case WifiEnterpriseConfig.Phase2.MSCHAPV2:
212                     phase2StringId = R.string.wifiopts_phase2_mschapv2;
213                     break;
214                 case WifiEnterpriseConfig.Phase2.GTC:
215                     phase2StringId = R.string.wifiopts_phase2_gtc;
216                     break;
217             }
218             if(phase2StringId > 0)
219                 phase2InfoView.setText(phase2StringId);
220             else
221                 phase2InfoView.setText("");
222
223             cacertInfoView.setText(settings.getCAName());
224         } else {
225
226         }
227         updateWifiConnectButton();
228     }
229
230     public void updateWifiState() {
231         NetworkInfo myNetworkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
232         WifiInfo myWifiInfo = wifiManager.getConnectionInfo();
233         String ssid = trimWifiSSID(myWifiInfo != null ? myWifiInfo.getSSID() : null);
234         if(ssid == null)
235             return;
236
237         WifiNetworkSettings settings = null;
238         for(int i = 0; i < wifiPresets.length; i++) {
239             if(wifiPresets[i].getSSID().equalsIgnoreCase(ssid)) {
240                 settings = wifiPresets[i];
241                 break;
242             }
243         }
244         if(settings == null)
245             return;
246
247         Resources resources = AppContext.getMainActivity().getResources();
248         String status;
249         if(myNetworkInfo.isConnectedOrConnecting()) {
250             int statusId = (myNetworkInfo.isConnected() ? R.string.wifisettings_status_connected : R.string.wifisettings_status_connecting);
251             status = String.format(resources.getString(statusId), ssid);
252         } else {
253             status = resources.getString(R.string.wifisettings_status_disconnected);
254         }
255         TextView statusTextView = (TextView)view.findViewById(R.id.wifiStatusText);
256         statusTextView.setText(status);
257
258         updateWifiConnectButton();
259     }
260
261     private void updateWifiScanState() {
262         networkScanned = true;
263         List<ScanResult> scanResultList = wifiManager.getScanResults();
264         for(int i = 0; i < wifiPresets.length; i++) {
265             boolean networkFound = false;
266             for(ScanResult result : scanResultList) {
267                 if(result.SSID != null && result.SSID.equalsIgnoreCase(wifiPresets[i].getSSID())) {
268                     networkFound = true;
269                     break;
270                 }
271             }
272             wifiPresets[i].isInScanResult = networkFound;
273         }
274         updateWifiConnectButton();
275     }
276
277     private void updateWifiConnectButton() {
278         if(selectedNetworkIndex >= wifiPresets.length)
279             return;
280         WifiNetworkSettings preset = wifiPresets[selectedNetworkIndex];
281
282         boolean buttonEnabled = false;
283         int buttonTextId = 0;
284         NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
285         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
286         WifiConfigurationManager.WifiConnectionStatus status = wifiConfigManager.getWifiState(preset);
287         String ssid = trimWifiSSID(wifiInfo != null ? wifiInfo.getSSID() : null);
288
289         Log.i("Wifi", ssid + "|" + preset.getSSID());
290
291         if(!wifiManager.isWifiEnabled()) {
292             buttonTextId = R.string.wifisettings_connect_button_disabled;
293         } else if(networkInfo.isConnectedOrConnecting() && ssid != null && ssid.equalsIgnoreCase(preset.getSSID()) && status == WifiConfigurationManager.WifiConnectionStatus.WIFISTATE_NULL) {
294             buttonTextId = R.string.wifisettings_connect_button_ready;
295         } else if(!networkScanned) {
296             buttonTextId = R.string.wifisettings_connect_button_scan;
297         } else if(!preset.isInScanResult) {
298             buttonTextId = R.string.wifisettings_connect_button_notfound;
299             buttonEnabled = true;
300         } else {
301             buttonTextId = 0;
302             if(status != WifiConfigurationManager.WifiConnectionStatus.WIFISTATE_NULL) {
303                 switch (status) {
304                     case WIFISTATE_CONNECTING:
305                         buttonTextId = R.string.wifisettings_connect_button_connecting;
306                         break;
307                     case WIFISTATE_AUTHENTICATING:
308                         buttonTextId = R.string.wifisettings_connect_button_authenticating;
309                         break;
310                     case WIFISTATE_CONNECTED:
311                         buttonTextId = R.string.wifisettings_connect_button_ready;
312                         break;
313                     case WIFISTATE_FAILED:
314                         buttonTextId = R.string.wifisettings_connect_button_failed;
315                         buttonEnabled = true;
316                         break;
317                 }
318             }
319             if(wifiConfigManager.isLocked(preset) && buttonTextId == 0) {
320                 buttonTextId = R.string.wifisettings_connect_button_connecting;
321             }
322
323             if(buttonTextId == 0) {
324                 buttonEnabled = true;
325                 buttonTextId = R.string.wifisettings_connect_button;
326             }
327         }
328
329         Button connectBtn = (Button) view.findViewById(R.id.wifiConnectBtn);
330         connectBtn.setEnabled(buttonEnabled);
331         connectBtn.setText(buttonTextId);
332     }
333
334     @Override
335     public View onCreateView(LayoutInflater inflater, ViewGroup container,
336                              Bundle savedInstanceState) {
337         view = inflater.inflate(R.layout.fragment_wifi_settings, container, false);
338         AppContext.setTitle("DHBW WLAN Settings");
339
340         updateSelectedNetworkInformation();
341
342         tablayout = (TabLayout) view.findViewById(R.id.tabs);
343         tablayout.removeAllTabs();
344         for(int i = 0; i < wifiPresets.length; i++) {
345             TabLayout.Tab tab = tablayout.newTab();
346             tab.setText(wifiPresets[i].getName());
347             tablayout.addTab(tab);
348         }
349         tablayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
350             @Override
351             public void onTabSelected(TabLayout.Tab tab) {
352                 selectedNetworkIndex = tab.getPosition();
353                 updateSelectedNetworkInformation();
354             }
355
356             @Override
357             public void onTabUnselected(TabLayout.Tab tab) {
358             }
359
360             @Override
361             public void onTabReselected(TabLayout.Tab tab) {
362             }
363         });
364
365         Button connectBtn = (Button) view.findViewById(R.id.wifiConnectBtn);
366         connectBtn.setOnClickListener(new View.OnClickListener() {
367             @Override
368             public void onClick(View v) {
369                 WifiNetworkSettings settings = wifiPresets[selectedNetworkIndex];
370                 if(!settings.isInScanResult) {
371                     networkScanned = false;
372                     wifiManager.startScan();
373                     updateWifiConnectButton();
374                     return;
375                 }
376
377
378
379                 EditText usernameEdt = (EditText) view.findViewById(R.id.wifiUsername);
380                 EditText passwordEdt = (EditText) view.findViewById(R.id.wifiPassword);
381
382                 String username = usernameEdt.getText().toString();
383                 String password = passwordEdt.getText().toString();
384
385                if (username.length() > 0 && password.length() > 0) {
386                     if(settings != null) {
387                         settings.setAuthData(username, password);
388
389                         wifiConfigManager.connect(settings);
390                     }
391
392                    updateWifiConnectButton();
393                 }
394             }
395         });
396
397         updateWifiState();
398         updateWifiScanState();
399
400         return view;
401     }
402
403     @Override
404     public void onResume() {
405         super.onResume();
406
407         if(AppContext == null)
408             AppContext = CampusAppContext.getInstance();
409
410         IntentFilter filter = new IntentFilter();
411         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
412         filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
413         AppContext.getMainActivity().registerReceiver(this.wifiStateReceiver, new IntentFilter(filter));
414         AppContext.getMainActivity().registerReceiver(this.wifiScanReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
415
416         networkScanned = false;
417         wifiManager.startScan();
418         updateWifiConnectButton();
419
420         Log.i("WifiSettings", "registered wifi state receiver");
421     }
422
423     @Override
424         public void onPause() {
425         super.onPause();
426
427         AppContext.getMainActivity().unregisterReceiver(this.wifiStateReceiver);
428         AppContext.getMainActivity().unregisterReceiver(this.wifiScanReceiver);
429
430         Log.i("WifiSettings", "unregistered wifi state receiver");
431     }
432
433 }