/******************************************************************************* * Copyright 2011 The Regents of the University of California * * 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 org.ohmage.triggers.base; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.ohmage.R; import org.ohmage.Utilities; import org.ohmage.db.DbHelper; import org.ohmage.db.Models.Campaign; import org.ohmage.logprobe.Log; import org.ohmage.triggers.config.NotifConfig; import org.ohmage.triggers.notif.NotifDesc; import org.ohmage.triggers.notif.Notifier; import org.ohmage.triggers.types.location.LocTrigMapsActivity; import org.ohmage.triggers.types.location.LocationTrigger; import org.ohmage.triggers.types.time.TimeTrigger; import org.ohmage.triggers.utils.TrigPrefManager; /* * Boot listener. Starts all the active triggers. * Also restores the pending notifications if any */ public class TriggerInit { private static final String TAG = "TriggerFramework"; public static void initTriggers(Context context, String campaignUrn) { Log.v(TAG, "TriggerInit: Initializing triggers for " + campaignUrn); TriggerTypeMap trigMap = new TriggerTypeMap(); TriggerDB db = new TriggerDB(context); db.open(); Cursor c = db.getAllTriggers(campaignUrn); if(c.moveToFirst()) { do { int trigId = c.getInt( c.getColumnIndexOrThrow(TriggerDB.KEY_ID)); String trigDesc = c.getString( c.getColumnIndexOrThrow(TriggerDB.KEY_TRIG_DESCRIPT)); String notifDesc = c.getString( c.getColumnIndexOrThrow(TriggerDB.KEY_NOTIF_DESCRIPT)); String trigType = c.getString( c.getColumnIndexOrThrow(TriggerDB.KEY_TRIG_TYPE)); String rtDesc = c.getString( c.getColumnIndexOrThrow(TriggerDB.KEY_RUNTIME_DESCRIPT)); String actDesc = c.getString( c.getColumnIndexOrThrow(TriggerDB.KEY_TRIG_ACTION_DESCRIPT)); Log.v(TAG, "TriggerInit: Read from db: " + trigId + ", " + trigDesc + ", " + actDesc); TriggerBase trig = trigMap.getTrigger(trigType); if(trig != null) { //Start the trigger TriggerActionDesc aDesc = new TriggerActionDesc(); //Start only if it has a positive number of surveys if(aDesc.loadString(actDesc) && aDesc.getCount() > 0) { Log.v(TAG, "TriggerInit: Starting trigger: " + trigId + ", " + trigDesc); trig.startTrigger(context, trigId, trigDesc); } //Restore the notification states for this trigger TriggerRunTimeDesc desc = new TriggerRunTimeDesc(); if(desc.loadString(rtDesc) && desc.hasTriggerTimeStamp()) { Log.v(TAG, "TriggerInit: Restoring notifications for " + trigId); Notifier.restorePastNotificationStates(context, trigId, notifDesc, desc.getTriggerTimeStamp()); } } } while(c.moveToNext()); } c.close(); db.close(); //Refresh the notification display Notifier.refreshNotification(context, campaignUrn, true); } /* * Resets all triggers, settings and preferences to its default. * Removes all triggers from the database after stopping them. */ public static boolean resetTriggersAndSettings(Context context, String campaignUrn) { Log.v(TAG, "TriggerInit: Resetting all triggers for " + campaignUrn); TriggerTypeMap trigMap = new TriggerTypeMap(); TriggerDB db = new TriggerDB(context); db.open(); Cursor c = db.getAllTriggers(campaignUrn); //Stop and delete all triggers if(c.moveToFirst()) { do { int trigId = c.getInt( c.getColumnIndexOrThrow(TriggerDB.KEY_ID)); TriggerBase trig = trigMap.getTrigger( db.getTriggerType(trigId)); if(trig != null) { //delete the trigger trig.deleteTrigger(context, trigId); } } while(c.moveToNext()); } c.close(); db.close(); //Refresh the notification display Notifier.refreshNotification(context, campaignUrn, true); //Clear all preference files registered with the preference manager TrigPrefManager.clearPreferenceFiles(context, campaignUrn); return true; } public static boolean resetAllTriggersAndSettings(Context context) { Log.v(TAG, "TriggerInit: Resetting all triggers"); DbHelper dbHelper = new DbHelper(context); for (Campaign c : dbHelper.getReadyCampaigns()) { resetTriggersAndSettings(context, c.mUrn); } TrigPrefManager.clearPreferenceFiles(context, "GLOBAL"); TriggerTypeMap trigMap = new TriggerTypeMap(); //Reset the settings of all trigger types for(TriggerBase trig : trigMap.getAllTriggers()) { if(trig.hasSettings()) { trig.resetSettings(context); } } SharedPreferences pref = context.getSharedPreferences(LocTrigMapsActivity.TOOL_TIP_PREF_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = pref.edit(); editor.putBoolean(LocTrigMapsActivity.KEY_TOOL_TIP_DO_NT_SHOW, false); editor.commit(); NotifDesc.setGlobalDesc(context, NotifConfig.defaultConfig); return true; } /** * <p>Adds default triggers read from R.raw.triggers in json format</p> * * <p>Examples:</p> * <ul> * <li>1) A time trigger for a specific survey in a campaign that goes off at 2:26 every day</li> * <li>2) A time trigger for a specific survey in a campaign that goes off at 3:30pm every day, but has a start and end time range of 3:00pm to 4:00pm</li> * <li>3) A time trigger for two different surveys in a campaign that goes off randomly between 3:00pm and 4:00pm every day</li> * <li>4) A location trigger for Home</li> * <li>5) A location trigger for Work that will only go off if you go there between 3:00pm and 4:00pm</li> * <li>6) A location trigger for Work that will go off at 4:00pm even if the location is not reached</li> * </ul> * <pre> * {@code * { * "triggers":[ * { * "campaign_urn":"urn:mo:chipts", * "type":"TimeTrigger", * "description":{"time":"14:26","repeat":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]}, * "action":{"surveys":["General Feeling Today"]} * }, * * { * "campaign_urn":"urn:mo:chipts", * "type":"TimeTrigger", * "description":{"start":"15:00","end":"16:00","time":"15:30","repeat":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]}, * "action":{"surveys":["General Feeling Today"]} * }, * * { * "campaign_urn":"urn:mo:chipts", * "type":"TimeTrigger", * "description":{"start":"15:00","end":"16:00","time":"random","repeat":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]}, * "action":{"surveys":["General Feeling Today","Medication"]} * }, * * { * "campaign_urn":"urn:mo:chipts", * "type":"LocationTrigger", * "description":{"location":"Home","min_reentry_interval":120}, * "action":{"surveys":["General Feeling Today","Medication"]} * }, * * { * "campaign_urn":"urn:mo:chipts", * "type":"LocationTrigger", * "description":{"time_range":{"trigger_always":false,"start":"15:00","end":"16:00"},"location":"Work","min_reentry_interval":120}, * "action":{"surveys":["General Feeling Today","Medication"]} * }, * * { * "campaign_urn":"urn:mo:chipts", * "type":"LocationTrigger", * "description":{"time_range":{"trigger_always":true,"start":"15:00","end":"16:00"},"location":"Work","min_reentry_interval":120}, * "action":{"surveys":["Medication"]} * } * ] * }</pre> * @param context * @param camapaignUrn - filter for triggers which have this campaignUrn (set to null for no filtering) */ public static void addDefaultTriggers(Context context, String campaignUrn) { try { JSONArray triggersList = new JSONObject(Utilities.convertStreamToString(context.getResources().openRawResource(R.raw.triggers))).getJSONArray("triggers"); for(int i=0;i<triggersList.length();i++) { JSONObject trigger = triggersList.getJSONObject(i); if(campaignUrn == null || campaignUrn.equals(trigger.getString("campaign_urn"))) { String type = trigger.getString("type"); if("TimeTrigger".equals(type)) { TimeTrigger time = new TimeTrigger(); time.addNewTrigger(context, trigger.getString("campaign_urn"), trigger.getString("description"), trigger.getString("action")); } else if("LocationTrigger".equals(type)) { LocationTrigger location = new LocationTrigger(); location.addNewTrigger(context, trigger.getString("campaign_urn"), trigger.getString("description"), trigger.getString("action")); } else { throw new RuntimeException("Unsupported trigger type"); } } } } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }