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