/*
* Copyright 2012 The Stanford MobiSocial Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package mobisocial.musubi.nearby.scanner;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import mobisocial.musubi.model.DbContactAttributes;
import mobisocial.musubi.model.MIdentity;
import mobisocial.musubi.nearby.item.NearbyItem;
import mobisocial.musubi.nearby.item.NearbyUser;
import mobisocial.socialkit.User;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.util.Log;
/**
* Scans the database for known location identifiers for users.
*
*/
public class AttributeScannerTask extends NearbyScannerTask {
final Context mContext;
final WifiManager mWifiManager;
public AttributeScannerTask(Context c, WifiManager wifiManager) {
mContext = c;
mWifiManager = wifiManager;
}
@Override
protected List<NearbyItem> doInBackground(Void... params) {
if (DBG) Log.d(TAG, "Scanning for nearby attributes...");
List<User> wifiUsers = DbContactAttributes.getUsersWithAttribute(
mContext, DbContactAttributes.ATTR_WIFI_SSID);
/** Compare your wifi fingerprint with your friends' **/
List<User> wifiFingerprintUsers = DbContactAttributes.getUsersWithAttribute(
mContext, DbContactAttributes.ATTR_WIFI_FINGERPRINT);
String myFingerprintString = DbContactAttributes.getDeviceAttribute(mContext, DbContactAttributes.ATTR_WIFI_FINGERPRINT);
if (myFingerprintString == null) {
myFingerprintString = "";
}
Set<String> myFingerprint = new HashSet<String>(Arrays.asList(myFingerprintString.split(":")));
if (myFingerprint.size() > 0) {
Log.w(TAG, "Checking over " + wifiFingerprintUsers.size() + " peers with wifi fingerprints");
for (User u : wifiFingerprintUsers) {
String theirFingerprintString = u.getAttribute(DbContactAttributes.ATTR_WIFI_FINGERPRINT);
if(theirFingerprintString == null) {
theirFingerprintString = "";
}
Set<String> theirFingerprint = new HashSet<String>(Arrays.asList(theirFingerprintString.split(":")));
if (theirFingerprint.size() > 0 && !(theirFingerprint.size() == 1 && theirFingerprint.toArray()[0].toString().length() == 0)) {
int comparisonSize = Math.min(myFingerprint.size(), theirFingerprint.size());
theirFingerprint.retainAll(myFingerprint);
int intersection = theirFingerprint.size();
//if there is a 50% match over the minimum comparison size, they're close enough
if((double)intersection / (double)comparisonSize >= .5) {
Log.w(TAG, "adding user " + u.getName() + " based on wifi fingerprint");
addNearbyItem(new NearbyUser(mContext, u));
}
}
}
}
/** Last known wifi address we found them on **/
String myWifi = mWifiManager.getConnectionInfo().getSSID(); // BSSID is narrower
Log.d(TAG, "Checking clients last checked in to " + myWifi);
if (myWifi != null) {
// TODO: this should be a single query..
Log.d(TAG, "Checking over " + wifiUsers.size() + " peers with known wifis");
for (User u : wifiUsers) {
String theirWifi = u.getAttribute(DbContactAttributes.ATTR_WIFI_SSID);
if (myWifi.equals(theirWifi)) {
Log.w(TAG, "adding user " + u.getName() + " based on wifi ssid");
addNearbyItem(new NearbyUser(mContext, u));
}
}
}
return null;
}
}