Added fake time feature

Change-Id: Ia5b59f94be730cb322c2aeacf117970a23e7af78
diff --git a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
index c314ee7..87b7925 100644
--- a/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
+++ b/bordeaux/service/src/android/bordeaux/services/AggregatorManager.java
@@ -34,6 +34,8 @@
     private static AggregatorManager mManager = null;
 
     private String mFakeLocation = null;
+    private String mFakeTimeOfDay = null;
+    private String mFakeDayOfWeek = null;
 
     private AggregatorManager() {
         sFeatureMap = new HashMap<String, Aggregator>();
@@ -75,10 +77,23 @@
         LocationStatsAggregator agg = (LocationStatsAggregator)
                 mAggregators.get(LocationStatsAggregator.class.getName());
         if (agg == null) return new ArrayList<String> ();
-        ArrayList<String> clusters = new ArrayList<String>();
         return agg.getClusterNames();
     }
 
+    public List<String> getTimeOfDayValues() {
+        TimeStatsAggregator agg = (TimeStatsAggregator)
+                mAggregators.get(TimeStatsAggregator.class.getName());
+        if (agg == null) return new ArrayList<String>();
+        return agg.getTimeOfDayValues();
+    }
+
+    public List<String> getDayOfWeekValues() {
+        TimeStatsAggregator agg = (TimeStatsAggregator)
+                mAggregators.get(TimeStatsAggregator.class.getName());
+        if (agg == null) return new ArrayList<String>();
+        return agg.getDayOfWeekValues();
+    }
+
     // Set an empty string "" to disable the fake location
     public boolean setFakeLocation(String location) {
         LocationStatsAggregator agg = (LocationStatsAggregator)
@@ -89,12 +104,36 @@
         return true;
     }
 
+    // Set an empty string "" to disable the fake time of day
+    public boolean setFakeTimeOfDay(String time_of_day) {
+        TimeStatsAggregator agg = (TimeStatsAggregator)
+                mAggregators.get(TimeStatsAggregator.class.getName());
+        if (agg == null) return false;
+        agg.setFakeTimeOfDay(time_of_day);
+        mFakeTimeOfDay = time_of_day;
+        return true;
+    }
+
+    // Set an empty string "" to disable the fake day of week
+    public boolean setFakeDayOfWeek(String day_of_week) {
+        TimeStatsAggregator agg = (TimeStatsAggregator)
+                mAggregators.get(TimeStatsAggregator.class.getName());
+        if (agg == null) return false;
+        agg.setFakeDayOfWeek(day_of_week);
+        mFakeDayOfWeek = day_of_week;
+        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;
+        if (mFakeTimeOfDay != null && mFakeTimeOfDay.length() != 0)
+            fakeMode = true;
+        if (mFakeDayOfWeek != null && mFakeDayOfWeek.length() != 0)
+            fakeMode = true;
         return fakeMode;
     }
     // End of IAggregatorManger interface
diff --git a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
index 659e847..7a01233 100644
--- a/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
+++ b/bordeaux/service/src/android/bordeaux/services/BordeauxAggregatorManager.java
@@ -72,6 +72,28 @@
         }
     }
 
+    public List<String> getTimeOfDayValues() {
+        if (!retrieveAggregatorManager())
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        try {
+            return mAggregatorManager.getTimeOfDayValues();
+        } catch (RemoteException e) {
+            Log.e(TAG,"Error getting time of day values");
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        }
+    }
+
+    public List<String> getDayOfWeekValues() {
+        if (!retrieveAggregatorManager())
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        try {
+            return mAggregatorManager.getDayOfWeekValues();
+        } catch (RemoteException e) {
+            Log.e(TAG,"Error getting day of week values");
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        }
+    }
+
     public boolean setFakeLocation(final String name) {
         if (!retrieveAggregatorManager())
             throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
@@ -83,6 +105,28 @@
         }
     }
 
+    public boolean setFakeTimeOfDay(final String time_of_day) {
+        if (!retrieveAggregatorManager())
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        try {
+            return mAggregatorManager.setFakeTimeOfDay(time_of_day);
+        } catch (RemoteException e) {
+            Log.e(TAG,"Error setting fake time of day:" + time_of_day);
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        }
+    }
+
+    public boolean setFakeDayOfWeek(final String day_of_week) {
+        if (!retrieveAggregatorManager())
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        try {
+            return mAggregatorManager.setFakeDayOfWeek(day_of_week);
+        } catch (RemoteException e) {
+            Log.e(TAG,"Error setting fake day of week:" + day_of_week);
+            throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
+        }
+    }
+
     public boolean getFakeMode() {
         if (!retrieveAggregatorManager())
             throw new RuntimeException(AggregatorManager_NOTAVAILABLE);
diff --git a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
index 1b2f067..06afb40 100644
--- a/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
+++ b/bordeaux/service/src/android/bordeaux/services/IAggregatorManager.aidl
@@ -24,7 +24,15 @@
     // TODO: remove the following interfaces in production
     // they are only used for demo purpose
     List<String> getLocationClusters();
+    List<String> getTimeOfDayValues();
+    List<String> getDayOfWeekValues();
     // use "" to disable the fake location
     boolean setFakeLocation(in String cluster);
+    // use "" to disable the fake time
+    boolean setFakeTimeOfDay(in String time_of_day);
+    // use "" to disable the fake day
+    boolean setFakeDayOfWeek(in String day_of_week);
+    // return whether the service is in fake mode
+    // it's in fake mode, if any of the location, time and day is fake
     boolean getFakeMode();
 }
diff --git a/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java b/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
index 2b94cd4..a3e123c 100644
--- a/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
+++ b/bordeaux/service/src/android/bordeaux/services/TimeStatsAggregator.java
@@ -19,7 +19,9 @@
 import android.text.format.Time;
 import android.util.Log;
 
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 // import java.util.Date;
@@ -52,6 +54,17 @@
     static final String DAYTIME = "Daytime";
     static final String NIGHTTIME = "Nighttime";
 
+    static String mFakeTimeOfDay = null;
+    static String mFakeDayOfWeek = null;
+
+    static final String[] TIME_OF_DAY_VALUES =
+       {MORNING, NOON, AFTERNOON, EVENING, NIGHT, LATENIGHT};
+
+    static final String[] DAY_OF_WEEK_VALUES =
+       {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY};
+
+    static final String[] DAYTIME_VALUES = {MORNING, NOON, AFTERNOON, EVENING};
+
     public String[] getListOfFeatures(){
         String [] list = new String[4];
         list[0] = TIME_OF_WEEK;
@@ -123,17 +136,64 @@
         Time time = new Time();
         time.set(utcTime);
 
-        features.put(DAY_OF_WEEK, getDayOfWeek(time.weekDay));
-        features.put(PERIOD_OF_DAY, getPeriodOfDay(time.hour));
-        features.put(TIME_OF_DAY, getTimeOfDay(time.hour));
+        if (mFakeTimeOfDay != null && mFakeTimeOfDay.length() != 0) {
+            List<String> day_list = Arrays.asList(DAYTIME_VALUES);
 
-        if (time.weekDay == Time.SUNDAY || time.weekDay == Time.SATURDAY ||
-                (time.weekDay == Time.FRIDAY &&
-                features.get(PERIOD_OF_DAY).equals(NIGHTTIME))) {
-            features.put(TIME_OF_WEEK, WEEKEND);
+            if (day_list.contains(mFakeTimeOfDay)) {
+                features.put(PERIOD_OF_DAY, DAYTIME);
+            } else {
+                features.put(PERIOD_OF_DAY, NIGHTTIME);
+            }
+            features.put(TIME_OF_DAY, mFakeTimeOfDay);
         } else {
-            features.put(TIME_OF_WEEK, WEEKDAY);
+            features.put(PERIOD_OF_DAY, getPeriodOfDay(time.hour));
+            features.put(TIME_OF_DAY, getTimeOfDay(time.hour));
         }
+
+        if (mFakeDayOfWeek != null && mFakeDayOfWeek.length() != 0) {
+            features.put(DAY_OF_WEEK, mFakeDayOfWeek);
+            if (mFakeDayOfWeek.equals(SUNDAY) ||
+                mFakeDayOfWeek.equals(SATURDAY) ||
+                mFakeDayOfWeek.equals(FRIDAY) &&
+                    features.get(PERIOD_OF_DAY).equals(NIGHTTIME)) {
+                features.put(TIME_OF_WEEK, WEEKEND);
+            } else {
+                features.put(TIME_OF_WEEK, WEEKDAY);
+            }
+        }
+        else {
+            features.put(DAY_OF_WEEK, getDayOfWeek(time.weekDay));
+            if (time.weekDay == Time.SUNDAY || time.weekDay == Time.SATURDAY ||
+                    (time.weekDay == Time.FRIDAY &&
+                    features.get(PERIOD_OF_DAY).equals(NIGHTTIME))) {
+                features.put(TIME_OF_WEEK, WEEKEND);
+            } else {
+                features.put(TIME_OF_WEEK, WEEKDAY);
+            }
+        }
+
         return features;
     }
+
+    // get all possible time_of_day values
+    public static List<String> getTimeOfDayValues() {
+        return Arrays.asList(TIME_OF_DAY_VALUES);
+    }
+
+    // get all possible day values
+    public static List<String> getDayOfWeekValues() {
+        return Arrays.asList(DAY_OF_WEEK_VALUES);
+    }
+
+    // set the fake time of day
+    // set to "" to disable the fake time
+    public static void setFakeTimeOfDay(String time_of_day) {
+        mFakeTimeOfDay = time_of_day;
+    }
+
+    // set the fake day of week
+    // set to "" to disable the fake day
+    public static void setFakeDayOfWeek(String day_of_week) {
+        mFakeDayOfWeek = day_of_week;
+    }
 }