/*
* Copyright 2012 Rui Araújo, Luís Fonseca
*
* This file is part of Router Keygen.
*
* Router Keygen is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Router Keygen is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Router Keygen. If not, see <http://www.gnu.org/licenses/>.
*/
package org.exobel.routerkeygen;
import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.Build;
import android.widget.Toast;
import org.exobel.routerkeygen.algorithms.WiFiNetwork;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.zip.ZipInputStream;
public class WifiScanReceiver extends BroadcastReceiver {
final private OnScanListener[] scanListeners;
final private WifiManager wifi;
private KeygenMatcherTask task;
public WifiScanReceiver(WifiManager wifi, OnScanListener... scanListener) {
this.scanListeners = scanListener;
this.wifi = wifi;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void onReceive(Context context, Intent intent) {
if (intent == null
|| !intent.getAction().equals(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION))
return;
if (scanListeners == null)
return;
if (wifi == null)
return;
try {
final List<ScanResult> results = wifi.getScanResults();
/*
* We have had reports of this returning null instead of empty
*/
if (results == null)
return;
try {
// Single scan
context.unregisterReceiver(this);
} catch (Exception e) {
e.printStackTrace();
}
if (task == null || task.getStatus() == Status.FINISHED) {
task = new KeygenMatcherTask(results, context);
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
task.execute();
} else {
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
} catch (SecurityException e) {
//Sometimes getScanResults triggers a SecurityException
}
}
public interface OnScanListener {
void onScanFinished(WiFiNetwork[] networks);
}
private class KeygenMatcherTask extends
AsyncTask<Void, Void, WiFiNetwork[]> {
private final List<ScanResult> results;
private final Context context;
private boolean misbuiltAPK = false;
public KeygenMatcherTask(List<ScanResult> results, Context context) {
this.results = results;
this.context = context;
}
@Override
protected void onPostExecute(WiFiNetwork[] networks) {
if (misbuiltAPK)
Toast.makeText(context, R.string.err_misbuilt_apk,
Toast.LENGTH_SHORT).show();
for (OnScanListener scanListener : scanListeners)
scanListener.onScanFinished(networks);
}
@Override
protected WiFiNetwork[] doInBackground(Void... params) {
final Set<WiFiNetwork> set = new TreeSet<>();
for (int i = 0; i < results.size() - 1; ++i)
for (int j = i + 1; j < results.size(); ++j)
if (results.get(i).SSID.equals(results.get(j).SSID))
results.remove(j--);
for (ScanResult result : results) {
try {
ZipInputStream magicInfo = new ZipInputStream(context
.getResources().openRawResource(R.raw.magic_info));
set.add(new WiFiNetwork(result, magicInfo));
magicInfo.close();
} catch (LinkageError e) {
misbuiltAPK = true;
} catch (NotFoundException | IOException e) {
e.printStackTrace();
}
}
final WiFiNetwork[] networks = new WiFiNetwork[set.size()];
final Iterator<WiFiNetwork> it = set.iterator();
int i = 0;
while (it.hasNext())
networks[i++] = it.next();
return networks;
}
}
}