summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Hua <whua@google.com>2012-08-28 13:46:31 -0700
committerWei Hua <whua@google.com>2012-08-29 15:23:10 -0700
commit9c3a7dc466e2f8de02e15030b2b7f4096ba97e5a (patch)
tree6dc99b2f5c5897637948952d358ccbe0e0017ba9
parent83954e853dc1e1a28b2c3efbe1585f188266df02 (diff)
downloadml-9c3a7dc466e2f8de02e15030b2b7f4096ba97e5a.tar.gz
Added Fake location support.
Change-Id: I894a135bf15f6d776f06b5e1c6b59db64ae745c1
-rw-r--r--bordeaux/service/src/android/bordeaux/services/AggregatorManager.java45
-rw-r--r--bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java33
-rw-r--r--bordeaux/service/src/android/bordeaux/services/ClusterManager.java162
-rw-r--r--bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl7
-rw-r--r--bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java22
5 files changed, 193 insertions, 76 deletions
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
index 42ccf9f22..c314ee7c0 100644
--- a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
+++ b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
@@ -20,15 +20,21 @@ package android.bordeaux.services;
import android.bordeaux.services.StringString;
import android.content.Context;
import android.util.Log;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.ArrayList;
class AggregatorManager extends IAggregatorManager.Stub {
private final String TAG = "AggregatorMnager";
- private static HashMap<String, Aggregator> sFeatureMap;
+ // this maps from the aggregator name to the registered aggregator instance
+ private static HashMap<String, Aggregator> mAggregators = new HashMap<String, Aggregator>();
+ // this maps from the feature names to the aggregator that generates the feature
+ private static HashMap<String, Aggregator> sFeatureMap = new HashMap<String, Aggregator>();
private static AggregatorManager mManager = null;
+ private String mFakeLocation = null;
+
private AggregatorManager() {
sFeatureMap = new HashMap<String, Aggregator>();
}
@@ -50,16 +56,49 @@ class AggregatorManager extends IAggregatorManager.Stub {
}
public void registerAggregator(Aggregator agg, AggregatorManager m) {
+ if (mAggregators.get(agg.getClass().getName()) != null) {
+ // only one instance
+ throw new RuntimeException("Can't register more than one instance");
+ }
+ mAggregators.put(agg.getClass().getName(), agg);
agg.setManager(m);
String[] fl = agg.getListOfFeatures();
for ( int i = 0; i< fl.length; i ++)
sFeatureMap.put(fl[i], agg);
}
-
+ // Start of IAggregatorManager interface
public ArrayList<StringString> getData(String dataName) {
return getList(getDataMap(dataName));
}
+ public List<String> getLocationClusters() {
+ LocationStatsAggregator agg = (LocationStatsAggregator)
+ mAggregators.get(LocationStatsAggregator.class.getName());
+ if (agg == null) return new ArrayList<String> ();
+ ArrayList<String> clusters = new ArrayList<String>();
+ return agg.getClusterNames();
+ }
+
+ // Set an empty string "" to disable the fake location
+ public boolean setFakeLocation(String location) {
+ LocationStatsAggregator agg = (LocationStatsAggregator)
+ mAggregators.get(LocationStatsAggregator.class.getName());
+ if (agg == null) return false;
+ agg.setFakeLocation(location);
+ mFakeLocation = location;
+ return true;
+ }
+
+ // Get the current mode, if fake mode return true
+ public boolean getFakeMode() {
+ boolean fakeMode = false;
+ // checking any features that are in the fake mode
+ if (mFakeLocation != null && mFakeLocation.length() != 0)
+ fakeMode = true;
+ return fakeMode;
+ }
+ // End of IAggregatorManger interface
+
public Map<String, String> getDataMap(String dataName) {
if (sFeatureMap.get(dataName) != null)
return sFeatureMap.get(dataName).getFeatureValue(dataName);
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
index 7e2346f2d..659e84799 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
@@ -61,6 +61,39 @@ public class BordeauxAggregatorManager {
}
}
+ public List<String> getLocationClusters() {
+ if (!retrieveAggregatorManager())
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ try {
+ return mAggregatorManager.getLocationClusters();
+ } catch (RemoteException e) {
+ Log.e(TAG,"Error getting location clusters");
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ }
+ }
+
+ public boolean setFakeLocation(final String name) {
+ if (!retrieveAggregatorManager())
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ try {
+ return mAggregatorManager.setFakeLocation(name);
+ } catch (RemoteException e) {
+ Log.e(TAG,"Error setting fake location:" + name);
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ }
+ }
+
+ public boolean getFakeMode() {
+ if (!retrieveAggregatorManager())
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ try {
+ return mAggregatorManager.getFakeMode();
+ } catch (RemoteException e) {
+ Log.e(TAG,"Error getting fake mode");
+ throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+ }
+ }
+
private Map<String, String> getMap(final List<StringString> sample) {
HashMap<String, String> map = new HashMap<String, String>();
for (int i =0; i < sample.size(); i++) {
diff --git a/bordeaux/service/src/android/bordeaux/services/ClusterManager.java b/bordeaux/service/src/android/bordeaux/services/ClusterManager.java
index f6217e328..b5d0b1a20 100644
--- a/bordeaux/service/src/android/bordeaux/services/ClusterManager.java
+++ b/bordeaux/service/src/android/bordeaux/services/ClusterManager.java
@@ -191,27 +191,29 @@ public class ClusterManager {
List<Map<String, String> > allData = mStorage.getAllData();
HashMap<String, Long> histogram = new HashMap<String, Long>();
- mSemanticClusters.clear();
- for (Map<String, String> map : allData) {
- String semanticId = map.get(SEMANTIC_ID);
- double longitude = Double.valueOf(map.get(SEMANTIC_LONGITUDE));
- double latitude = Double.valueOf(map.get(SEMANTIC_LATITUDE));
- SemanticCluster cluster = new SemanticCluster(
- semanticId, longitude, latitude, CONSOLIDATE_INTERVAL);
-
- histogram.clear();
- for (int i = mFeatureValueStart; i <= mFeatureValueEnd; i++) {
- String featureValue = SEMANTIC_COLUMNS[i];
- if (map.containsKey(featureValue)) {
- histogram.put(featureValue, Long.valueOf(map.get(featureValue)));
+ synchronized (mSemanticClusters) {
+ mSemanticClusters.clear();
+ for (Map<String, String> map : allData) {
+ String semanticId = map.get(SEMANTIC_ID);
+ double longitude = Double.valueOf(map.get(SEMANTIC_LONGITUDE));
+ double latitude = Double.valueOf(map.get(SEMANTIC_LATITUDE));
+ SemanticCluster cluster = new SemanticCluster(
+ semanticId, longitude, latitude, CONSOLIDATE_INTERVAL);
+
+ histogram.clear();
+ for (int i = mFeatureValueStart; i <= mFeatureValueEnd; i++) {
+ String featureValue = SEMANTIC_COLUMNS[i];
+ if (map.containsKey(featureValue)) {
+ histogram.put(featureValue, Long.valueOf(map.get(featureValue)));
+ }
}
+ cluster.setHistogram(histogram);
+
+ mSemanticClusters.add(cluster);
}
- cluster.setHistogram(histogram);
- mSemanticClusters.add(cluster);
+ mSemanticClusterCount = mSemanticClusters.size();
}
-
- mSemanticClusterCount = mSemanticClusters.size();
Log.e(TAG, "load " + mSemanticClusterCount + " semantic clusters.");
}
@@ -219,76 +221,80 @@ public class ClusterManager {
HashMap<String, String> rowFeatures = new HashMap<String, String>();
Log.e(TAG, "save " + mSemanticClusters.size() + " semantic clusters.");
- mStorage.removeAllData();
- for (SemanticCluster cluster : mSemanticClusters) {
- rowFeatures.clear();
- rowFeatures.put(SEMANTIC_ID, cluster.getSemanticId());
+ synchronized (mSemanticClusters) {
+ mStorage.removeAllData();
+ for (SemanticCluster cluster : mSemanticClusters) {
+ rowFeatures.clear();
+ rowFeatures.put(SEMANTIC_ID, cluster.getSemanticId());
- rowFeatures.put(SEMANTIC_LONGITUDE,
- String.valueOf(cluster.getCenterLongitude()));
- rowFeatures.put(SEMANTIC_LATITUDE,
- String.valueOf(cluster.getCenterLatitude()));
+ rowFeatures.put(SEMANTIC_LONGITUDE,
+ String.valueOf(cluster.getCenterLongitude()));
+ rowFeatures.put(SEMANTIC_LATITUDE,
+ String.valueOf(cluster.getCenterLatitude()));
- HashMap<String, Long> histogram = cluster.getHistogram();
- for (Map.Entry<String, Long> entry : histogram.entrySet()) {
- rowFeatures.put(entry.getKey(), String.valueOf(entry.getValue()));
+ HashMap<String, Long> histogram = cluster.getHistogram();
+ for (Map.Entry<String, Long> entry : histogram.entrySet()) {
+ rowFeatures.put(entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ mStorage.addData(rowFeatures);
}
- mStorage.addData(rowFeatures);
}
}
private void updateSemanticClusters() {
HashMap<String, ArrayList<BaseCluster> > semanticMap =
new HashMap<String, ArrayList<BaseCluster> >();
- for (SemanticCluster cluster : mSemanticClusters) {
- String semanticId = cluster.getSemanticId();
- semanticMap.put(cluster.getSemanticId(), new ArrayList<BaseCluster>());
- semanticMap.get(semanticId).add(cluster);
- }
-
- // select candidate location clusters
- ArrayList<LocationCluster> candidates = new ArrayList<LocationCluster>();
- for (LocationCluster cluster : mLocClusters) {
- if (cluster.passThreshold(SEMANTIC_CLUSTER_THRESHOLD)) {
- candidates.add(cluster);
+ synchronized (mSemanticClusters) {
+ for (SemanticCluster cluster : mSemanticClusters) {
+ String semanticId = cluster.getSemanticId();
+ semanticMap.put(cluster.getSemanticId(), new ArrayList<BaseCluster>());
+ semanticMap.get(semanticId).add(cluster);
}
- }
- // assign each candidate to a semantic cluster
- for (LocationCluster candidate : candidates) {
- if (candidate.hasSemanticId()) {
- // candidate has been assigned to a semantic cluster
- continue;
+ // select candidate location clusters
+ ArrayList<LocationCluster> candidates = new ArrayList<LocationCluster>();
+ for (LocationCluster cluster : mLocClusters) {
+ if (cluster.passThreshold(SEMANTIC_CLUSTER_THRESHOLD)) {
+ candidates.add(cluster);
+ }
}
- // find the closest semantic cluster
- float bestClusterDistance = Float.MAX_VALUE;
- SemanticCluster bestCluster = null;
- for (SemanticCluster cluster : mSemanticClusters) {
- float distance = cluster.distanceToCluster(candidate);
- Log.e(TAG, "distance to semantic cluster: " + cluster.getSemanticId());
+ // assign each candidate to a semantic cluster
+ for (LocationCluster candidate : candidates) {
+ if (candidate.hasSemanticId()) {
+ // candidate has been assigned to a semantic cluster
+ continue;
+ }
- if (distance < bestClusterDistance) {
- bestClusterDistance = distance;
- bestCluster = cluster;
+ // find the closest semantic cluster
+ float bestClusterDistance = Float.MAX_VALUE;
+ SemanticCluster bestCluster = null;
+ for (SemanticCluster cluster : mSemanticClusters) {
+ float distance = cluster.distanceToCluster(candidate);
+ Log.e(TAG, "distance to semantic cluster: " + cluster.getSemanticId());
+
+ if (distance < bestClusterDistance) {
+ bestClusterDistance = distance;
+ bestCluster = cluster;
+ }
}
- }
- // add the location to the selected cluster
- SemanticCluster semanticCluster;
- if (bestClusterDistance > SEMANTIC_CLUSTER_RADIUS) {
- // if it is far away from all existing clusters, create a new cluster.
- bestCluster = new SemanticCluster(candidate, CONSOLIDATE_INTERVAL,
- mSemanticClusterCount++);
- String id = bestCluster.getSemanticId();
- semanticMap.put(id, new ArrayList<BaseCluster>());
- semanticMap.get(id).add(bestCluster);
+ // add the location to the selected cluster
+ SemanticCluster semanticCluster;
+ if (bestClusterDistance > SEMANTIC_CLUSTER_RADIUS) {
+ // if it is far away from all existing clusters, create a new cluster.
+ bestCluster = new SemanticCluster(candidate, CONSOLIDATE_INTERVAL,
+ mSemanticClusterCount++);
+ String id = bestCluster.getSemanticId();
+ semanticMap.put(id, new ArrayList<BaseCluster>());
+ semanticMap.get(id).add(bestCluster);
+ }
+ String semanticId = bestCluster.getSemanticId();
+ candidate.setSemanticId(semanticId);
+ semanticMap.get(semanticId).add(candidate);
}
- String semanticId = bestCluster.getSemanticId();
- candidate.setSemanticId(semanticId);
- semanticMap.get(semanticId).add(candidate);
+ candidates.clear();
}
- candidates.clear();
Log.e(TAG, "number of semantic clusters: " + semanticMap.size());
// use candidates semantic cluster
@@ -316,12 +322,24 @@ public class ClusterManager {
// instead of using the last location, try acquiring the latest location.
if (mLastLocation != null) {
// TODO: use fast neatest neighbor search speed up location search
- for (SemanticCluster cluster: mSemanticClusters) {
- if (cluster.distanceToCenter(mLastLocation) < SEMANTIC_CLUSTER_RADIUS) {
- return cluster.getSemanticId();
+ synchronized (mSemanticClusters) {
+ for (SemanticCluster cluster: mSemanticClusters) {
+ if (cluster.distanceToCenter(mLastLocation) < SEMANTIC_CLUSTER_RADIUS) {
+ return cluster.getSemanticId();
+ }
}
}
}
return label;
}
+
+ public List<String> getClusterNames() {
+ ArrayList<String> clusters = new ArrayList<String>();
+ synchronized (mSemanticClusters) {
+ for (SemanticCluster cluster: mSemanticClusters) {
+ clusters.add(cluster.getSemanticId());
+ }
+ }
+ return clusters;
+ }
}
diff --git a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
index 65028be41..1b2f06797 100644
--- a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
+++ b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
@@ -20,4 +20,11 @@ import android.bordeaux.services.StringString;
interface IAggregatorManager {
List<StringString> getData(in String dataName);
+
+ // TODO: remove the following interfaces in production
+ // they are only used for demo purpose
+ List<String> getLocationClusters();
+ // use "" to disable the fake location
+ boolean setFakeLocation(in String cluster);
+ boolean getFakeMode();
}
diff --git a/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
index 0c4dddbb5..0c05157c2 100644
--- a/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
+++ b/bordeaux/service/src/android/bordeaux/services/LocationStatsAggregator.java
@@ -29,6 +29,7 @@ import android.os.Message;
import android.os.Process;
import android.util.Log;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
// TODO: add functionality to detect speed (use GPS) when needed
@@ -57,6 +58,9 @@ public class LocationStatsAggregator extends Aggregator {
private LocationManager mLocationManager;
private ClusterManager mClusterManager;
+ // Fake location, used for testing.
+ private String mFakeLocation = null;
+
public LocationStatsAggregator(final Context context) {
mLocationManager =
(LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
@@ -82,12 +86,28 @@ public class LocationStatsAggregator extends Aggregator {
String location = mClusterManager.getSemanticLocation();
if (!location.equals(UNKNOWN_LOCATION)) {
- feature.put(CURRENT_LOCATION, location);
+ if (mFakeLocation != null) {
+ feature.put(CURRENT_LOCATION, mFakeLocation);
+ } else {
+ feature.put(CURRENT_LOCATION, location);
+ }
}
}
return (Map) feature;
}
+ public List<String> getClusterNames() {
+ return mClusterManager.getClusterNames();
+ }
+
+ // set a fake location using cluster name.
+ // Set an empty string "" to disable the fake location
+ public void setFakeLocation(String name) {
+ if (name != null && name.length() != 0)
+ mFakeLocation = name;
+ else mFakeLocation = null;
+ }
+
private void setClusteringThread(Context context) {
mClusterManager = new ClusterManager(context);