2021-02-16 13:42:49 +01:00
package com.jens.automation2 ;
2021-12-04 02:39:37 +01:00
import static com.jens.automation2.Trigger.triggerParameter2Split ;
2021-03-28 20:33:44 +02:00
import android.annotation.SuppressLint ;
2021-02-16 13:42:49 +01:00
import android.content.Context ;
import android.os.AsyncTask ;
2022-02-27 18:01:54 +01:00
import android.os.Build ;
2021-02-16 13:42:49 +01:00
import android.os.Looper ;
import android.util.Log ;
import android.widget.Toast ;
import com.google.android.gms.location.DetectedActivity ;
import com.jens.automation2.receivers.ActivityDetectionReceiver ;
2022-05-23 20:28:56 +02:00
import com.jens.automation2.receivers.BroadcastListener ;
2021-02-16 13:42:49 +01:00
import java.util.ArrayList ;
import java.util.Calendar ;
import java.util.Date ;
2022-01-04 17:51:27 +01:00
import java.util.List ;
2021-02-16 13:42:49 +01:00
public class Rule implements Comparable < Rule >
{
2022-04-04 20:21:34 +02:00
protected static ArrayList < Rule > ruleCollection = new ArrayList < Rule > ( ) ;
2022-02-27 18:01:54 +01:00
2022-04-04 20:21:34 +02:00
protected static List < Rule > ruleRunHistory = new ArrayList < Rule > ( ) ;
2021-02-16 13:42:49 +01:00
2022-01-04 17:51:27 +01:00
public static List < Rule > getRuleRunHistory ( )
2021-02-16 13:42:49 +01:00
{
return ruleRunHistory ;
}
2022-04-04 20:21:34 +02:00
protected ArrayList < Trigger > triggerSet ;
protected ArrayList < Action > actionSet ;
protected String name ;
protected boolean ruleActive = true ; // rules can be deactivated, so they won't fire if you don't want them temporarily
protected boolean ruleToggle = false ; // rule will run again and do the opposite of its actions if applicable
protected Calendar lastExecution ;
protected static Date lastActivatedRuleActivationTime ;
2021-03-30 23:06:07 +02:00
public Calendar getLastExecution ( )
{
return lastExecution ;
}
public void setLastExecution ( Calendar lastExecution )
{
this . lastExecution = lastExecution ;
}
2021-02-16 13:42:49 +01:00
public boolean isRuleToggle ( )
{
return ruleToggle ;
}
public void setRuleToggle ( boolean ruleToggle )
{
this . ruleToggle = ruleToggle ;
}
public static ArrayList < Rule > getRuleCollection ( )
{
return ruleCollection ;
}
public boolean isRuleActive ( )
{
return ruleActive ;
}
public void setRuleActive ( boolean ruleActive )
{
this . ruleActive = ruleActive ;
}
public static void setRuleCollection ( ArrayList < Rule > ruleCollection )
{
Rule . ruleCollection = ruleCollection ;
}
public static Date getLastActivatedRuleActivationTime ( )
{
return lastActivatedRuleActivationTime ;
}
public static Rule getLastActivatedRule ( )
{
if ( ruleRunHistory . size ( ) > 0 )
return ruleRunHistory . get ( 0 ) ;
else
return null ;
}
public ArrayList < Trigger > getTriggerSet ( )
{
return triggerSet ;
}
public void setTriggerSet ( ArrayList < Trigger > triggerSet )
{
this . triggerSet = triggerSet ;
}
public ArrayList < Action > getActionSet ( )
{
return actionSet ;
}
public void setActionSet ( ArrayList < Action > actionSet )
{
this . actionSet = actionSet ;
}
public String getName ( )
{
return name ;
}
public void setName ( String name )
{
2023-01-01 23:51:51 +01:00
this . name = name . trim ( ) ;
2021-02-16 13:42:49 +01:00
}
public static void readFromFile ( )
{
ruleCollection = XmlFileInterface . ruleCollection ;
}
@Override
public String toString ( )
{
return this . getName ( ) ;
}
2021-03-28 20:33:44 +02:00
@SuppressLint ( " NewApi " )
2021-02-16 13:42:49 +01:00
public String toStringLong ( )
{
String returnString = " " ;
if ( isRuleActive ( ) )
returnString + = " Active: " ;
else
returnString + = " Inactive: " ;
returnString + = this . getName ( ) + " : If " ;
for ( int i = 0 ; i < this . getTriggerSet ( ) . size ( ) ; i + + )
{
returnString + = this . getTriggerSet ( ) . get ( i ) . toString ( ) ;
if ( i ! = this . getTriggerSet ( ) . size ( ) - 1 ) //if not the last loop
returnString + = " and " ;
}
returnString + = " then " ;
for ( int i = 0 ; i < this . getActionSet ( ) . size ( ) ; i + + )
{
returnString + = this . getActionSet ( ) . get ( i ) . toString ( ) ;
if ( i ! = this . getActionSet ( ) . size ( ) - 1 ) //if not the last loop
returnString + = " and " ;
}
return returnString ;
}
public boolean create ( Context context )
{
if ( this . checkBeforeSaving ( context , false ) )
{
Miscellaneous . logEvent ( " i " , " Rule " , " Creating rule: " + this . toString ( ) , 3 ) ;
ruleCollection . add ( this ) ;
boolean returnValue = XmlFileInterface . writeFile ( ) ;
2021-06-20 22:24:17 +02:00
try
{
XmlFileInterface . readFile ( ) ;
}
catch ( Exception e )
{
Miscellaneous . logEvent ( " w " , " Read file " , Log . getStackTraceString ( e ) , 3 ) ;
}
2021-02-16 13:42:49 +01:00
if ( returnValue )
{
AutomationService service = AutomationService . getInstance ( ) ;
if ( service ! = null )
service . applySettingsAndRules ( ) ;
}
return returnValue ;
}
else
return false ;
}
public boolean change ( Context context )
{
if ( this . checkBeforeSaving ( context , true ) )
{
Miscellaneous . logEvent ( " i " , " Rule " , " Changing rule: " + this . toString ( ) , 3 ) ;
2022-04-04 20:21:34 +02:00
2021-02-16 13:42:49 +01:00
boolean returnValue = XmlFileInterface . writeFile ( ) ;
if ( returnValue )
{
AutomationService service = AutomationService . getInstance ( ) ;
if ( service ! = null )
service . applySettingsAndRules ( ) ;
}
return returnValue ;
}
else
return false ;
}
public boolean delete ( )
{
Miscellaneous . logEvent ( " i " , " Rule " , " Deleting rule: " + this . toString ( ) , 3 ) ;
ruleCollection . remove ( this ) ;
AutomationService service = AutomationService . getInstance ( ) ;
if ( service ! = null )
service . applySettingsAndRules ( ) ;
return XmlFileInterface . writeFile ( ) ;
}
2021-06-20 22:24:17 +02:00
public boolean cloneRule ( Context context )
{
Rule newRule = new Rule ( ) ;
newRule . setName ( this . getName ( ) + " - clone " ) ;
newRule . setRuleActive ( this . isRuleActive ( ) ) ;
newRule . setRuleToggle ( this . isRuleToggle ( ) ) ;
newRule . setTriggerSet ( this . getTriggerSet ( ) ) ;
newRule . setActionSet ( this . getActionSet ( ) ) ;
return newRule . create ( context ) ;
}
2021-02-16 13:42:49 +01:00
private boolean checkBeforeSaving ( Context context , boolean changeExistingRule )
{
2021-05-13 18:37:34 +02:00
if ( this . getName ( ) = = null | | this . getName ( ) . length ( ) = = 0 )
2021-02-16 13:42:49 +01:00
{
Toast . makeText ( context , context . getResources ( ) . getString ( R . string . pleaseEnterValidName ) , Toast . LENGTH_LONG ) . show ( ) ;
return false ;
}
if ( ! changeExistingRule )
2022-04-03 20:25:10 +02:00
{
for ( Rule rule : Rule . ruleCollection )
{
if ( rule . getName ( ) . equals ( this . getName ( ) ) )
2021-02-16 13:42:49 +01:00
{
Toast . makeText ( context , context . getResources ( ) . getString ( R . string . anotherRuleByThatName ) , Toast . LENGTH_LONG ) . show ( ) ;
return false ;
}
2022-04-03 20:25:10 +02:00
}
}
if ( this . getTriggerSet ( ) . size ( ) = = 0 )
2021-02-16 13:42:49 +01:00
{
Toast . makeText ( context , context . getResources ( ) . getString ( R . string . pleaseSpecifiyTrigger ) , Toast . LENGTH_LONG ) . show ( ) ;
return false ;
}
2022-04-03 20:25:10 +02:00
if ( this . getActionSet ( ) . size ( ) = = 0 )
2021-02-16 13:42:49 +01:00
{
Toast . makeText ( context , context . getResources ( ) . getString ( R . string . pleaseSpecifiyAction ) , Toast . LENGTH_LONG ) . show ( ) ;
return false ;
}
return true ;
}
public boolean isActuallyToggable ( )
{
boolean result = hasToggableTrigger ( ) & & hasToggableAction ( ) ;
if ( result )
Miscellaneous . logEvent ( " i " , " Rule " , String . format ( Miscellaneous . getAnyContext ( ) . getString ( R . string . ruleToggable ) , this . getName ( ) ) , 4 ) ;
else
Miscellaneous . logEvent ( " i " , " Rule " , String . format ( Miscellaneous . getAnyContext ( ) . getString ( R . string . ruleNotToggable ) , this . getName ( ) ) , 4 ) ;
return result ;
}
private boolean hasToggableTrigger ( )
{
for ( Trigger trigger : this . getTriggerSet ( ) )
{
switch ( trigger . getTriggerType ( ) )
{
case airplaneMode :
break ;
case batteryLevel :
break ;
case charging :
break ;
case nfcTag :
return true ;
case noiseLevel :
break ;
case phoneCall :
break ;
case pointOfInterest :
break ;
case process_started_stopped :
break ;
case roaming :
break ;
case speed :
break ;
case timeFrame :
break ;
case usb_host_connection :
break ;
case wifiConnection :
break ;
default :
break ;
}
}
return false ;
}
private boolean hasToggableAction ( )
{
for ( Action action : this . getActionSet ( ) )
{
// Is there any action that can just be switched?
switch ( action . getAction ( ) )
{
case setAirplaneMode :
case setBluetooth :
case setDataConnection :
case setDisplayRotation :
case setUsbTethering :
case setWifi :
case setWifiTethering :
2021-11-15 20:28:38 +01:00
case setBluetoothTethering :
return true ;
2021-02-16 13:42:49 +01:00
default :
break ;
}
}
return false ;
}
2021-12-04 02:39:37 +01:00
public boolean hasNotAppliedSinceLastExecution ( )
{
for ( Trigger oneTrigger : this . getTriggerSet ( ) )
{
if ( oneTrigger . hasStateNotAppliedSinceLastRuleExecution ( ) )
return true ;
2022-03-26 20:00:19 +01:00
/ *
Workaround for repetition in TimeFrame triggers
* /
if ( oneTrigger . getTriggerType ( ) . equals ( Trigger . Trigger_Enum . timeFrame ) )
{
if ( oneTrigger . getTimeFrame ( ) . repetition > 0 )
2023-01-16 16:54:54 +01:00
{
if ( this . getLastExecution ( ) ! = null )
{
Calendar now = Calendar . getInstance ( ) ;
if ( this . getLastExecution ( ) . getTimeInMillis ( ) + oneTrigger . getTimeFrame ( ) . getRepetition ( ) * 1000 < = now . getTimeInMillis ( ) )
return true ;
}
else
return true ;
}
2022-03-26 20:00:19 +01:00
}
2022-05-23 20:28:56 +02:00
else if ( oneTrigger . getTriggerType ( ) . equals ( Trigger . Trigger_Enum . broadcastReceived ) )
{
return oneTrigger . getTriggerParameter ( ) = = BroadcastListener . getInstance ( ) . hasBroadcastOccurredSince ( oneTrigger . getTriggerParameter2 ( ) , getLastExecution ( ) ) ;
}
2021-12-04 02:39:37 +01:00
}
return false ;
}
2021-12-07 23:10:37 +01:00
public boolean getsGreenLight ( Context context )
{
2021-12-09 18:03:00 +01:00
if ( applies ( context ) )
{
if ( hasNotAppliedSinceLastExecution ( ) )
2022-02-14 20:06:20 +01:00
{
Miscellaneous . logEvent ( " i " , " getsGreenLight() " , " Rule " + getName ( ) + " applies and has flipped since its last execution. " , 4 ) ;
2021-12-09 18:03:00 +01:00
return true ;
2022-02-14 20:06:20 +01:00
}
2021-12-09 18:03:00 +01:00
else
Miscellaneous . logEvent ( " i " , " getsGreenLight() " , " Rule " + getName ( ) + " has not flipped since its last execution. " , 4 ) ;
}
else
Miscellaneous . logEvent ( " i " , " getsGreenLight() " , " Rule " + getName ( ) + " does not apply. " , 4 ) ;
return false ;
2021-12-07 23:10:37 +01:00
}
2021-02-16 13:42:49 +01:00
public boolean applies ( Context context )
{
if ( AutomationService . getInstance ( ) = = null )
{
2021-12-09 18:03:00 +01:00
Miscellaneous . logEvent ( " i " , " RuleCheck " , " Automation service not running. Rule " + getName ( ) + " cannot apply. " , 3 ) ;
2021-02-16 13:42:49 +01:00
return false ;
}
if ( this . ruleActive )
{
for ( Trigger oneTrigger : this . getTriggerSet ( ) )
{
2021-12-04 13:24:43 +01:00
if ( ! oneTrigger . applies ( null , context ) )
return false ;
2021-02-16 13:42:49 +01:00
}
2022-02-12 20:04:19 +01:00
Miscellaneous . logEvent ( " i " , String . format ( context . getResources ( ) . getString ( R . string . ruleCheckOf ) , this . getName ( ) ) , String . format ( " Rule %1$s generally applies currently. Checking if it's really due, yet will be done separately. " , this . getName ( ) ) , 3 ) ;
2021-02-16 13:42:49 +01:00
return true ;
}
2022-07-17 23:40:17 +02:00
Miscellaneous . logEvent ( " i " , String . format ( context . getResources ( ) . getString ( R . string . ruleCheckOf ) , this . getName ( ) ) , String . format ( context . getResources ( ) . getString ( R . string . ruleIsDeactivatedCantApply ) , this . getName ( ) ) , 4 ) ;
2021-02-16 13:42:49 +01:00
return false ;
}
2021-06-12 02:27:51 +02:00
2021-12-04 13:24:43 +01:00
/ * *
* This is actually a function of the class Trigger , but Rule is already distinguished by flavors , Trigger is not .
* Hence it is here .
* @param oneTrigger
* @return
* /
boolean checkActivityDetection ( Trigger oneTrigger )
{
if ( ActivityDetectionReceiver . getActivityDetectionLastResult ( ) ! = null )
{
boolean found = false ;
for ( DetectedActivity oneDetectedActivity : ActivityDetectionReceiver . getActivityDetectionLastResult ( ) . getProbableActivities ( ) )
{
if ( oneDetectedActivity . getType ( ) = = oneTrigger . getActivityDetectionType ( ) )
found = true ;
}
if ( ! found )
{
2021-12-09 18:03:00 +01:00
Miscellaneous . logEvent ( " i " , String . format ( Miscellaneous . getAnyContext ( ) . getResources ( ) . getString ( R . string . ruleCheckOf ) , this . getName ( ) ) , String . format ( Miscellaneous . getAnyContext ( ) . getResources ( ) . getString ( R . string . ruleDoesntApplyActivityNotPresent ) , getName ( ) , ActivityDetectionReceiver . getDescription ( oneTrigger . getActivityDetectionType ( ) ) ) , 3 ) ;
2021-12-04 13:24:43 +01:00
return false ;
}
else
{
for ( DetectedActivity oneDetectedActivity : ActivityDetectionReceiver . getActivityDetectionLastResult ( ) . getProbableActivities ( ) )
{
if ( oneDetectedActivity . getType ( ) = = oneTrigger . getActivityDetectionType ( ) & & oneDetectedActivity . getConfidence ( ) < Settings . activityDetectionRequiredProbability )
{
2021-12-09 18:03:00 +01:00
Miscellaneous . logEvent ( " i " , String . format ( Miscellaneous . getAnyContext ( ) . getResources ( ) . getString ( R . string . ruleCheckOf ) , this . getName ( ) ) , String . format ( Miscellaneous . getAnyContext ( ) . getResources ( ) . getString ( R . string . ruleDoesntApplyActivityGivenButTooLowProbability ) , getName ( ) , ActivityDetectionReceiver . getDescription ( oneDetectedActivity . getType ( ) ) , String . valueOf ( oneDetectedActivity . getConfidence ( ) ) , String . valueOf ( Settings . activityDetectionRequiredProbability ) ) , 3 ) ;
2021-12-04 13:24:43 +01:00
return false ;
}
}
}
}
return true ;
}
2021-02-16 13:42:49 +01:00
private class ActivateRuleTask extends AsyncTask < Object , String , Void >
{
2021-03-30 19:52:31 +02:00
boolean wasActivated = false ;
2021-02-16 13:42:49 +01:00
@Override
protected Void doInBackground ( Object . . . params )
{
// Miscellaneous.logEvent("i", "Rule", ((Context) params[0]).getResources().getString(R.string.usingNewThreadForRuleExecution), 5);
Thread . setDefaultUncaughtExceptionHandler ( Miscellaneous . uncaughtExceptionHandler ) ;
2022-02-20 18:57:13 +01:00
// without this line the debugger will - for some reason - skip all breakpoints in this class
2021-02-16 13:42:49 +01:00
if ( android . os . Debug . isDebuggerConnected ( ) )
android . os . Debug . waitForDebugger ( ) ;
if ( Looper . myLooper ( ) = = null )
Looper . prepare ( ) ;
2021-12-04 13:24:43 +01:00
setLastExecution ( Calendar . getInstance ( ) ) ;
2022-02-20 18:57:13 +01:00
wasActivated = activateInternally ( ( AutomationService ) params [ 0 ] ) ;
2021-02-16 13:42:49 +01:00
return null ;
}
@Override
protected void onProgressUpdate ( String . . . messages )
{
AutomationService service = AutomationService . getInstance ( ) ;
service . speak ( messages [ 0 ] , false ) ;
2023-02-01 23:29:26 +01:00
if ( Settings . showToasts )
Toast . makeText ( service , messages [ 0 ] , Toast . LENGTH_LONG ) . show ( ) ;
2021-02-16 13:42:49 +01:00
super . onProgressUpdate ( messages ) ;
}
@Override
protected void onPostExecute ( Void result )
{
2021-03-30 19:52:31 +02:00
/ *
Only update if the rules was actually executed . Became necessary for the notification trigger . If a user created a rule
with a notification trigger and this app creates a notification itself this will otherwise end in an infinite loop .
* /
if ( wasActivated )
{
2021-12-04 13:24:43 +01:00
// setLastExecution(Calendar.getInstance());
2021-03-30 19:52:31 +02:00
AutomationService . updateNotification ( ) ;
ActivityMainScreen . updateMainScreen ( ) ;
super . onPostExecute ( result ) ;
}
}
2021-02-16 13:42:49 +01:00
/ * *
* Will activate the rule . Should be called by a separate execution thread
* @param automationService
* /
2022-02-20 18:57:13 +01:00
protected boolean activateInternally ( AutomationService automationService )
2021-02-16 13:42:49 +01:00
{
2022-02-20 18:57:13 +01:00
boolean isActuallyToggleable = isActuallyToggable ( ) ;
2021-03-30 19:52:31 +02:00
2021-02-16 13:42:49 +01:00
boolean notLastActive = getLastActivatedRule ( ) = = null | | ! getLastActivatedRule ( ) . equals ( Rule . this ) ;
2022-02-20 18:57:13 +01:00
boolean doToggle = ruleToggle & & isActuallyToggleable ;
String message ;
if ( ! doToggle )
message = String . format ( automationService . getResources ( ) . getString ( R . string . ruleActivate ) , Rule . this . getName ( ) ) ;
else
message = String . format ( automationService . getResources ( ) . getString ( R . string . ruleActivateToggle ) , Rule . this . getName ( ) ) ;
Miscellaneous . logEvent ( " i " , " Rule " , message , 2 ) ;
2021-03-30 19:52:31 +02:00
2022-02-20 18:57:13 +01:00
if ( Settings . startNewThreadForRuleActivation )
publishProgress ( message ) ;
2021-03-30 19:52:31 +02:00
2022-02-20 18:57:13 +01:00
for ( int i = 0 ; i < Rule . this . getActionSet ( ) . size ( ) ; i + + )
{
2021-02-16 13:42:49 +01:00
try
{
2022-02-20 18:57:13 +01:00
Rule . this . getActionSet ( ) . get ( i ) . run ( automationService , doToggle ) ;
2021-02-16 13:42:49 +01:00
}
catch ( Exception e )
{
2022-02-20 18:57:13 +01:00
Miscellaneous . logEvent ( " e " , " RuleExecution " , " Error running action of rule " + Rule . this . getName ( ) + " : " + Log . getStackTraceString ( e ) , 1 ) ;
2021-02-16 13:42:49 +01:00
}
2022-02-20 18:57:13 +01:00
}
// Keep log of last x rule activations (Settings)
try
{
Rule . ruleRunHistory . add ( 0 , Rule . this ) ; // add at beginning for better visualization
Rule . lastActivatedRuleActivationTime = new Date ( ) ;
while ( ruleRunHistory . size ( ) > Settings . rulesThatHaveBeenRanHistorySize )
ruleRunHistory . remove ( ruleRunHistory . size ( ) - 1 ) ;
String history = " " ;
for ( Rule rule : ruleRunHistory )
history + = rule . getName ( ) + " , " ;
if ( history . length ( ) > 0 )
history = history . substring ( 0 , history . length ( ) - 2 ) ;
Miscellaneous . logEvent ( " i " , " Rule history " , " Most recent first: " + history , 4 ) ;
}
catch ( Exception e )
{
Miscellaneous . logEvent ( " e " , " Rule history error " , Log . getStackTraceString ( e ) , 3 ) ;
}
2021-02-16 13:42:49 +01:00
2022-02-20 18:57:13 +01:00
Miscellaneous . logEvent ( " i " , " Rule " , String . format ( Miscellaneous . getAnyContext ( ) . getResources ( ) . getString ( R . string . ruleActivationComplete ) , Rule . this . getName ( ) ) , 2 ) ;
2021-03-30 19:52:31 +02:00
return true ;
}
}
2021-02-16 13:42:49 +01:00
public void activate ( AutomationService automationService , boolean force )
{
ActivateRuleTask task = new ActivateRuleTask ( ) ;
2022-02-27 18:01:54 +01:00
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . HONEYCOMB )
task . executeOnExecutor ( AsyncTask . THREAD_POOL_EXECUTOR , automationService , force ) ;
else
task . execute ( automationService , force ) ;
2021-02-16 13:42:49 +01:00
}
2021-12-13 20:03:00 +01:00
public static ArrayList < Rule > findRuleCandidates ( Trigger . Trigger_Enum triggerType )
{
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( Rule oneRule : ruleCollection )
{
2022-02-27 18:01:54 +01:00
innerLoop :
2021-12-13 20:03:00 +01:00
for ( Trigger oneTrigger : oneRule . getTriggerSet ( ) )
{
2022-01-22 02:20:34 +01:00
if ( oneTrigger . getTriggerType ( ) . equals ( triggerType ) )
2021-12-13 20:03:00 +01:00
{
ruleCandidates . add ( oneRule ) ;
2022-02-27 18:01:54 +01:00
break innerLoop ; // we don't need to check the other triggers in the same rule
2021-12-13 20:03:00 +01:00
}
}
}
return ruleCandidates ;
}
2022-01-22 02:20:34 +01:00
public static ArrayList < Rule > findRuleCandidates ( Action . Action_Enum actionType )
{
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( Rule oneRule : ruleCollection )
{
innerloop :
for ( Action oneAction : oneRule . getActionSet ( ) )
{
if ( oneAction . getAction ( ) . equals ( actionType ) )
{
ruleCandidates . add ( oneRule ) ;
break innerloop ; // we don't need to check the other actions in the same rule
}
}
}
return ruleCandidates ;
}
2021-02-16 13:42:49 +01:00
public static ArrayList < Rule > findRuleCandidatesByPoi ( PointOfInterest searchPoi , boolean triggerParameter )
{
Miscellaneous . logEvent ( " i " , " RuleSearch " , " Searching for rules referencing POI " + searchPoi . getName ( ) + " . Total size of ruleset: " + String . valueOf ( ruleCollection . size ( ) ) , 4 ) ;
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( int i = 0 ; i < ruleCollection . size ( ) ; i + + )
{
innerloop :
for ( int j = 0 ; j < ruleCollection . get ( i ) . getTriggerSet ( ) . size ( ) ; j + + )
{
if ( ruleCollection . get ( i ) . getTriggerSet ( ) . get ( j ) . getTriggerType ( ) = = Trigger . Trigger_Enum . pointOfInterest )
{
if ( ruleCollection . get ( i ) . getTriggerSet ( ) . get ( j ) . getTriggerParameter ( ) = = triggerParameter )
{
if ( ruleCollection . get ( i ) . getTriggerSet ( ) . get ( j ) . getPointOfInterest ( ) ! = null & & ruleCollection . get ( i ) . getTriggerSet ( ) . get ( j ) . getPointOfInterest ( ) . equals ( searchPoi ) )
{
// Miscellaneous.logEvent("i", "RuleSearch", "Rule found with POI " + searchPoi.getName() + ". Checking if parameter is correct");
ruleCandidates . add ( ruleCollection . get ( i ) ) ;
break innerloop ; //if the poi is found we don't need to search the other triggers in the same rule
}
}
else
{
if ( ruleCollection . get ( i ) . getTriggerSet ( ) . get ( j ) . getPointOfInterest ( ) = = null )
{
// Miscellaneous.logEvent("i", "RuleSearch", "Rule found with POI " + searchPoi.getName() + ". Checking if parameter is correct");
ruleCandidates . add ( ruleCollection . get ( i ) ) ;
break innerloop ; //if the poi is found we don't need to search the other triggers in the same rule
}
}
}
}
}
if ( ruleCandidates . size ( ) = = 0 )
Miscellaneous . logEvent ( " i " , " RuleSearch " , " No rule with Poi " + searchPoi . getName ( ) + " found. " , 3 ) ;
return ruleCandidates ;
}
public static ArrayList < Rule > findRuleCandidatesByPoi ( PointOfInterest searchPoi )
{
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( Rule oneRule : ruleCollection )
{
innerloop :
for ( Trigger oneTrigger : oneRule . getTriggerSet ( ) )
{
if ( oneTrigger . getTriggerType ( ) = = Trigger . Trigger_Enum . pointOfInterest )
{
if ( oneTrigger . getPointOfInterest ( ) ! = null & & oneTrigger . getPointOfInterest ( ) . equals ( searchPoi ) ) // != null to exclude those who are referring all locations ("entering any location")
{
ruleCandidates . add ( oneRule ) ;
break innerloop ; //if the poi is found we don't need to search the other triggers in the same rule
}
}
}
}
return ruleCandidates ;
}
2022-01-05 18:06:26 +01:00
public static ArrayList < Rule > findRuleCandidatesByTriggerProfile ( Profile profile )
{
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( Rule oneRule : ruleCollection )
{
innerloop :
for ( Trigger oneTrigger : oneRule . getTriggerSet ( ) )
{
if ( oneTrigger . getTriggerType ( ) = = Trigger . Trigger_Enum . profileActive )
{
String profileName = oneTrigger . getTriggerParameter2 ( ) . split ( triggerParameter2Split ) [ 0 ] ;
if ( profileName . equals ( profile . getName ( ) ) )
{
ruleCandidates . add ( oneRule ) ;
break innerloop ; //if the profile is found we don't need to search the other triggers in the same rule
}
}
}
}
return ruleCandidates ;
}
2021-02-16 13:42:49 +01:00
2022-01-05 18:06:26 +01:00
public static ArrayList < Rule > findRuleCandidatesByActionProfile ( Profile profile )
2021-02-16 13:42:49 +01:00
{
ArrayList < Rule > ruleCandidates = new ArrayList < Rule > ( ) ;
for ( Rule oneRule : ruleCollection )
{
innerloop :
for ( Action oneAction : oneRule . getActionSet ( ) )
{
if ( oneAction . getAction ( ) = = Action . Action_Enum . changeSoundProfile )
{
if ( oneAction . getParameter2 ( ) . equals ( profile . getOldName ( ) ) ) // != null to exclude those who are referring all locations ("entering any location")
{
ruleCandidates . add ( oneRule ) ;
break innerloop ; //if the profile is found we don't need to search the other triggers in the same rule
}
}
}
}
return ruleCandidates ;
}
public static boolean isAnyRuleUsing ( Trigger . Trigger_Enum triggerType )
{
for ( Rule rule : ruleCollection )
{
if ( rule . isRuleActive ( ) )
{
for ( Trigger trigger : rule . getTriggerSet ( ) )
{
if ( trigger . getTriggerType ( ) . equals ( triggerType ) )
{
Miscellaneous . logEvent ( " i " , " Rule->isAnyRuleUsing() " , String . format ( Miscellaneous . getAnyContext ( ) . getString ( R . string . atLeastRuleXisUsingY ) , rule . getName ( ) , triggerType . getFullName ( Miscellaneous . getAnyContext ( ) ) ) , 5 ) ;
return true ;
}
}
}
}
return false ;
}
public static boolean isAnyRuleUsing ( Action . Action_Enum actionType )
{
for ( Rule rule : ruleCollection )
{
if ( rule . isRuleActive ( ) )
{
for ( Action action : rule . getActionSet ( ) )
{
if ( action . getAction ( ) . equals ( actionType ) )
{
Miscellaneous . logEvent ( " i " , " Rule->isAnyRuleUsing() " , String . format ( Miscellaneous . getAnyContext ( ) . getString ( R . string . atLeastRuleXisUsingY ) , rule . getName ( ) , actionType . getFullName ( Miscellaneous . getAnyContext ( ) ) ) , 5 ) ;
return true ;
}
}
}
}
return false ;
}
@Override
public int compareTo ( Rule another )
{
return this . getName ( ) . compareTo ( another . getName ( ) ) ;
}
public boolean haveEnoughPermissions ( )
{
return ActivityPermissions . havePermissionsForRule ( this , Miscellaneous . getAnyContext ( ) ) ;
}
2022-02-03 13:41:05 +01:00
public static Rule getByName ( String ruleName )
{
for ( Rule r : Rule . getRuleCollection ( ) )
{
if ( r . getName ( ) . equals ( ruleName ) )
return r ;
}
return null ;
}
2022-01-22 02:20:34 +01:00
}