forked from jens/Automation
Rework
This commit is contained in:
parent
d28ee8d00d
commit
cdf1a8baa8
13
.idea/deploymentTargetDropDown.xml
generated
13
.idea/deploymentTargetDropDown.xml
generated
@ -1,6 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="deploymentTargetDropDown">
|
<component name="deploymentTargetDropDown">
|
||||||
|
<runningDeviceTargetSelectedWithDropDown>
|
||||||
|
<Target>
|
||||||
|
<type value="RUNNING_DEVICE_TARGET" />
|
||||||
|
<deviceKey>
|
||||||
|
<Key>
|
||||||
|
<type value="VIRTUAL_DEVICE_PATH" />
|
||||||
|
<value value="C:\Users\jens\.android\avd\Android_11.avd" />
|
||||||
|
</Key>
|
||||||
|
</deviceKey>
|
||||||
|
</Target>
|
||||||
|
</runningDeviceTargetSelectedWithDropDown>
|
||||||
<targetSelectedWithDropDown>
|
<targetSelectedWithDropDown>
|
||||||
<Target>
|
<Target>
|
||||||
<type value="QUICK_BOOT_TARGET" />
|
<type value="QUICK_BOOT_TARGET" />
|
||||||
@ -12,6 +23,6 @@
|
|||||||
</deviceKey>
|
</deviceKey>
|
||||||
</Target>
|
</Target>
|
||||||
</targetSelectedWithDropDown>
|
</targetSelectedWithDropDown>
|
||||||
<timeTargetWasSelectedWithDropDown value="2021-11-26T17:59:37.692012Z" />
|
<timeTargetWasSelectedWithDropDown value="2021-12-04T01:10:17.133406Z" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@ -1,44 +1,22 @@
|
|||||||
package com.jens.automation2;
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.service.notification.StatusBarNotification;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.gms.location.DetectedActivity;
|
import com.google.android.gms.location.DetectedActivity;
|
||||||
import com.jens.automation2.location.LocationProvider;
|
|
||||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
|
||||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||||
import com.jens.automation2.receivers.BatteryReceiver;
|
|
||||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
|
||||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
|
||||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
|
||||||
import com.jens.automation2.receivers.NfcReceiver;
|
|
||||||
import com.jens.automation2.receivers.NoiseListener;
|
|
||||||
import com.jens.automation2.receivers.NotificationListener;
|
|
||||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
|
||||||
import com.jens.automation2.receivers.ProcessListener;
|
|
||||||
|
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
public class Rule implements Comparable<Rule>
|
public class Rule implements Comparable<Rule>
|
||||||
{
|
{
|
||||||
@ -357,6 +335,17 @@ public class Rule implements Comparable<Rule>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasNotAppliedSinceLastExecution()
|
||||||
|
{
|
||||||
|
for(Trigger oneTrigger : this.getTriggerSet())
|
||||||
|
{
|
||||||
|
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean applies(Context context)
|
public boolean applies(Context context)
|
||||||
{
|
{
|
||||||
if(AutomationService.getInstance() == null)
|
if(AutomationService.getInstance() == null)
|
||||||
@ -461,32 +450,6 @@ public class Rule implements Comparable<Rule>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean haveTriggersReallyChanged(Object triggeringObject)
|
|
||||||
{
|
|
||||||
boolean returnValue = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for(int i=0; i < triggerSet.size(); i++)
|
|
||||||
{
|
|
||||||
Trigger t = (Trigger) triggerSet.get(i);
|
|
||||||
|
|
||||||
if(t.hasStateRecentlyNotApplied(triggeringObject))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule \"" + getName() + "\" has trigger that flipped: " + t.toString(), 4);
|
|
||||||
returnValue = true; // only 1 trigger needs to have flipped recently
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("e", "Rule", "Error while checking if rule \"" + getName() + "\" haveTriggersReallyChanged(): " + Log.getStackTraceString(e), 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will activate the rule. Should be called by a separate execution thread
|
* Will activate the rule. Should be called by a separate execution thread
|
||||||
* @param automationService
|
* @param automationService
|
||||||
@ -497,9 +460,9 @@ public class Rule implements Comparable<Rule>
|
|||||||
|
|
||||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||||
boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
|
|
||||||
|
|
||||||
if(notLastActive || force || doToggle || triggersApplyAnew)
|
//if(notLastActive || force || doToggle)
|
||||||
|
if(force || doToggle)
|
||||||
{
|
{
|
||||||
String message;
|
String message;
|
||||||
if(!doToggle)
|
if(!doToggle)
|
||||||
|
@ -294,7 +294,7 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
|
|||||||
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
|
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
|
||||||
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
|
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
|
||||||
{
|
{
|
||||||
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
|
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()) && allRulesWithActivityDetection.get(i).hasNotAppliedSinceLastExecution())
|
||||||
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
|
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package com.jens.automation2;
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@ -15,31 +17,13 @@ import android.util.Log;
|
|||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.gms.location.DetectedActivity;
|
import com.google.android.gms.location.DetectedActivity;
|
||||||
import com.jens.automation2.location.LocationProvider;
|
|
||||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
|
||||||
import com.jens.automation2.receivers.BatteryReceiver;
|
|
||||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
|
||||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
|
||||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
|
||||||
import com.jens.automation2.receivers.NfcReceiver;
|
|
||||||
import com.jens.automation2.receivers.NoiseListener;
|
|
||||||
import com.jens.automation2.receivers.NotificationListener;
|
|
||||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
|
||||||
import com.jens.automation2.receivers.ProcessListener;
|
|
||||||
|
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
|
||||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
|
||||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
public class Rule implements Comparable<Rule>
|
public class Rule implements Comparable<Rule>
|
||||||
{
|
{
|
||||||
@ -358,6 +342,17 @@ public class Rule implements Comparable<Rule>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasNotAppliedSinceLastExecution()
|
||||||
|
{
|
||||||
|
for(Trigger oneTrigger : this.getTriggerSet())
|
||||||
|
{
|
||||||
|
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean applies(Context context)
|
public boolean applies(Context context)
|
||||||
{
|
{
|
||||||
if(AutomationService.getInstance() == null)
|
if(AutomationService.getInstance() == null)
|
||||||
@ -370,539 +365,9 @@ public class Rule implements Comparable<Rule>
|
|||||||
{
|
{
|
||||||
for(Trigger oneTrigger : this.getTriggerSet())
|
for(Trigger oneTrigger : this.getTriggerSet())
|
||||||
{
|
{
|
||||||
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.pointOfInterest))
|
if (!oneTrigger.applies(null, context))
|
||||||
{
|
|
||||||
// Am I here?
|
|
||||||
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
|
||||||
if(activePoi != null) //entering one
|
|
||||||
{
|
|
||||||
if(oneTrigger.getPointOfInterest() != null)
|
|
||||||
{
|
|
||||||
if(activePoi.equals(oneTrigger.getPointOfInterest()))
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're entering POI: " + oneTrigger.getPointOfInterest().getName() + ", not leaving it.", 4);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. This is " + activePoi.getName() + ", not " + oneTrigger.getPointOfInterest().getName() + ".", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getPointOfInterest() == null)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at a POI. Rule specifies not at none, so leaving any.", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //leaving one
|
|
||||||
{
|
|
||||||
// We are not at any POI. But if this trigger requires us NOT to be there, that may be fine.
|
|
||||||
if(oneTrigger.getPointOfInterest() != null)
|
|
||||||
{
|
|
||||||
// if(activePoi.equals(oneTrigger.getPointOfInterest()))
|
|
||||||
// {
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "We are not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\". But since that's required by this rule that's fine.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\".", 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getPointOfInterest() == null)
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at no POI. Rule specifies to be at anyone.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
|
|
||||||
{
|
|
||||||
Date now = new Date();
|
|
||||||
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
|
|
||||||
Time nowTime = Time.valueOf(timeString);
|
|
||||||
Calendar calNow = Calendar.getInstance();
|
|
||||||
|
|
||||||
|
|
||||||
if(oneTrigger.getTimeFrame().getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK)))
|
|
||||||
{
|
|
||||||
if(
|
|
||||||
// Regular case, start time is lower than end time
|
|
||||||
(
|
|
||||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
|
||||||
&&
|
|
||||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0
|
|
||||||
)
|
|
||||||
||
|
|
||||||
// Other case, start time higher than end time, timeframe goes over midnight
|
|
||||||
(
|
|
||||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0
|
|
||||||
&&
|
|
||||||
(Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
|
||||||
||
|
|
||||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// We are in the timeframe
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + "). Trigger of Rule " + this.getName() + " applies.", 3);
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 3);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the time. Trigger of Rule " + this.getName() + " doesn\'t apply..", 5);
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 5);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the day. Trigger of Rule " + this.getName() + " doesn\'t apply.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.charging))
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.isDeviceCharging(context) == 0)
|
|
||||||
{
|
|
||||||
return false; // unknown charging state, can't activate rule under these conditions
|
|
||||||
}
|
|
||||||
else if(BatteryReceiver.isDeviceCharging(context) == 1)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter()) //rule says when charging, but we're currently discharging
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(BatteryReceiver.isDeviceCharging(context) == 2)
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter()) //rule says when discharging, but we're currently charging
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.usb_host_connection))
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.isUsbHostConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.batteryLevel))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.speed))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.noiseLevel))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(NoiseListener.getNoiseLevelDb() < oneTrigger.getNoiseLevelDb())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsQuieterThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(NoiseListener.getNoiseLevelDb() > oneTrigger.getNoiseLevelDb())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsLouderThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.wifiConnection))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4);
|
|
||||||
if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4);
|
|
||||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2()))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name matches. Rule will apply.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No wifi name specified, any will do.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi state not correct, demanded " + String.valueOf(oneTrigger.getTriggerParameter() + ", got " + String.valueOf(WifiBroadcastReceiver.lastConnectedState)), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.process_started_stopped))
|
|
||||||
{
|
|
||||||
boolean running = ProcessListener.getRunningApps().contains(oneTrigger.getProcessName());
|
|
||||||
|
|
||||||
if(running)
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is currently running.", 4);
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is not running.", 4);
|
|
||||||
|
|
||||||
if(running != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger doesn't apply.", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger applies.", 4);
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.airplaneMode))
|
|
||||||
{
|
|
||||||
if(ConnectivityReceiver.isAirplaneMode(context) != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.roaming))
|
|
||||||
{
|
|
||||||
if(ConnectivityReceiver.isRoaming(context) != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall))
|
|
||||||
{
|
|
||||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
|
||||||
// state dir number
|
|
||||||
|
|
||||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2])))
|
|
||||||
{
|
|
||||||
//if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
|
||||||
if(
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING)
|
|
||||||
||
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK)
|
|
||||||
||
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if(
|
|
||||||
elements[1].equals(Trigger.triggerPhoneCallDirectionAny)
|
|
||||||
||
|
|
||||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1)
|
|
||||||
||
|
|
||||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Trigger conditions are met
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong direction. Demanded: " + String.valueOf(oneTrigger.getPhoneDirection()) + ", got: " + String.valueOf(PhoneStatusListener.getLastPhoneDirection()), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong call status. Demanded: " + String.valueOf(oneTrigger.getTriggerParameter()) + ", got: " + String.valueOf(PhoneStatusListener.isInACall()), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag))
|
|
||||||
{
|
|
||||||
if(NfcReceiver.lastReadLabel == null)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNoTagLabel), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(!NfcReceiver.lastReadLabel.equals(oneTrigger.getNfcTagId()))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongTagLabel) + " " + NfcReceiver.lastReadLabel + " / " + oneTrigger.getNfcTagId(), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.bluetoothConnection))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
|
|
||||||
|
|
||||||
if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// range
|
|
||||||
if(BluetoothReceiver.isAnyDeviceInRange() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// range
|
|
||||||
if(BluetoothReceiver.isAnyDeviceInRange() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getBluetoothDeviceAddress().length() > 0)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// range
|
|
||||||
if(BluetoothReceiver.isDeviceInRange(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyStateNotCorrect), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged))
|
|
||||||
{
|
|
||||||
if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
if(oneTrigger.getHeadphoneType() != 2 && oneTrigger.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification))
|
|
||||||
{
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
|
||||||
{
|
|
||||||
String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
|
||||||
|
|
||||||
String myApp = params[0];
|
|
||||||
String myTitleDir = params[1];
|
|
||||||
String requiredTitle = params[2];
|
|
||||||
String myTextDir = params[3];
|
|
||||||
String requiredText;
|
|
||||||
if (params.length >= 5)
|
|
||||||
requiredText = params[4];
|
|
||||||
else
|
|
||||||
requiredText = "";
|
|
||||||
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
// Check an active notification that is still there
|
|
||||||
|
|
||||||
boolean foundMatch = false;
|
|
||||||
|
|
||||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
|
||||||
{
|
|
||||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
|
||||||
{
|
|
||||||
String notificationApp = sbn.getPackageName();
|
|
||||||
String notificationTitle = null;
|
|
||||||
String notificationText = null;
|
|
||||||
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + notificationApp + ", title: " + notificationTitle + ", text: " + notificationText, 5);
|
|
||||||
|
|
||||||
if (!myApp.equals("-1"))
|
|
||||||
{
|
|
||||||
if (!notificationApp.equalsIgnoreCase(myApp))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(myApp.equals(BuildConfig.APPLICATION_ID))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
If there are multiple notifications ("stacked") title or text might be null:
|
|
||||||
https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications
|
|
||||||
*/
|
|
||||||
|
|
||||||
Bundle extras = sbn.getNotification().extras;
|
|
||||||
|
|
||||||
// T I T L E
|
|
||||||
if (extras.containsKey(EXTRA_TITLE))
|
|
||||||
notificationTitle = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(requiredTitle))
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTitleDir, requiredTitle, notificationTitle))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required title for a notification trigger was not specified.", 5);
|
|
||||||
|
|
||||||
// T E X T
|
|
||||||
|
|
||||||
if (extras.containsKey(EXTRA_TEXT))
|
|
||||||
notificationText = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(requiredText))
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTextDir, requiredText, notificationText))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5);
|
|
||||||
|
|
||||||
foundMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!foundMatch)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check a notification that is gone
|
|
||||||
|
|
||||||
if(NotificationListener.getLastNotification() != null)
|
|
||||||
{
|
|
||||||
if(!NotificationListener.getLastNotification().isCreated())
|
|
||||||
{
|
|
||||||
String app = NotificationListener.getLastNotification().getApp();
|
|
||||||
String title = NotificationListener.getLastNotification().getTitle();
|
|
||||||
String text = NotificationListener.getLastNotification().getText();
|
|
||||||
|
|
||||||
if (!myApp.equals("-1"))
|
|
||||||
{
|
|
||||||
if (!app.equalsIgnoreCase(myApp))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(myApp.equals(BuildConfig.APPLICATION_ID))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requiredTitle.length() > 0)
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTitleDir, title, requiredTitle))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requiredText.length() > 0)
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTextDir, text, requiredText))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -960,32 +425,6 @@ public class Rule implements Comparable<Rule>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean haveTriggersReallyChanged(Object triggeringObject)
|
|
||||||
{
|
|
||||||
boolean returnValue = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for(int i=0; i < triggerSet.size(); i++)
|
|
||||||
{
|
|
||||||
Trigger t = (Trigger) triggerSet.get(i);
|
|
||||||
|
|
||||||
if(t.hasStateRecentlyNotApplied(triggeringObject))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule \"" + getName() + "\" has trigger that flipped: " + t.toString(), 4);
|
|
||||||
returnValue = true; // only 1 trigger needs to have flipped recently
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("e", "Rule", "Error while checking if rule \"" + getName() + "\" haveTriggersReallyChanged(): " + Log.getStackTraceString(e), 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will activate the rule. Should be called by a separate execution thread
|
* Will activate the rule. Should be called by a separate execution thread
|
||||||
* @param automationService
|
* @param automationService
|
||||||
@ -996,9 +435,9 @@ public class Rule implements Comparable<Rule>
|
|||||||
|
|
||||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||||
boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
|
|
||||||
|
|
||||||
if(notLastActive || force || doToggle || triggersApplyAnew)
|
//if(notLastActive || force || doToggle)
|
||||||
|
if(force || doToggle)
|
||||||
{
|
{
|
||||||
String message;
|
String message;
|
||||||
if(!doToggle)
|
if(!doToggle)
|
||||||
|
@ -1,46 +1,22 @@
|
|||||||
package com.jens.automation2;
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.service.notification.StatusBarNotification;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.android.gms.location.DetectedActivity;
|
import com.google.android.gms.location.DetectedActivity;
|
||||||
import com.jens.automation2.location.LocationProvider;
|
|
||||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
|
||||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||||
import com.jens.automation2.receivers.BatteryReceiver;
|
|
||||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
|
||||||
import com.jens.automation2.receivers.ConnectivityReceiver;
|
|
||||||
import com.jens.automation2.receivers.HeadphoneJackListener;
|
|
||||||
import com.jens.automation2.receivers.NfcReceiver;
|
|
||||||
import com.jens.automation2.receivers.NoiseListener;
|
|
||||||
import com.jens.automation2.receivers.NotificationListener;
|
|
||||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
|
||||||
import com.jens.automation2.receivers.ProcessListener;
|
|
||||||
|
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
|
||||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
|
||||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
public class Rule implements Comparable<Rule>
|
public class Rule implements Comparable<Rule>
|
||||||
{
|
{
|
||||||
@ -359,6 +335,17 @@ public class Rule implements Comparable<Rule>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasNotAppliedSinceLastExecution()
|
||||||
|
{
|
||||||
|
for(Trigger oneTrigger : this.getTriggerSet())
|
||||||
|
{
|
||||||
|
if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean applies(Context context)
|
public boolean applies(Context context)
|
||||||
{
|
{
|
||||||
if(AutomationService.getInstance() == null)
|
if(AutomationService.getInstance() == null)
|
||||||
@ -371,344 +358,27 @@ public class Rule implements Comparable<Rule>
|
|||||||
{
|
{
|
||||||
for(Trigger oneTrigger : this.getTriggerSet())
|
for(Trigger oneTrigger : this.getTriggerSet())
|
||||||
{
|
{
|
||||||
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.pointOfInterest))
|
if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.activityDetection))
|
||||||
{
|
{
|
||||||
// Am I here?
|
if (ActivityDetectionReceiver.getActivityDetectionLastResult() != null)
|
||||||
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
|
||||||
if(activePoi != null) //entering one
|
|
||||||
{
|
|
||||||
if(oneTrigger.getPointOfInterest() != null)
|
|
||||||
{
|
|
||||||
if(activePoi.equals(oneTrigger.getPointOfInterest()))
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're entering POI: " + oneTrigger.getPointOfInterest().getName() + ", not leaving it.", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. This is " + activePoi.getName() + ", not " + oneTrigger.getPointOfInterest().getName() + ".", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getPointOfInterest() == null)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at a POI. Rule specifies not at none, so leaving any.", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else //leaving one
|
|
||||||
{
|
|
||||||
// We are not at any POI. But if this trigger requires us NOT to be there, that may be fine.
|
|
||||||
if(oneTrigger.getPointOfInterest() != null)
|
|
||||||
{
|
|
||||||
// if(activePoi.equals(oneTrigger.getPointOfInterest()))
|
|
||||||
// {
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "We are not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\". But since that's required by this rule that's fine.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're not at POI \"" + oneTrigger.getPointOfInterest().getName() + "\".", 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getPointOfInterest() == null)
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Rule doesn't apply. We're at no POI. Rule specifies to be at anyone.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.timeFrame))
|
|
||||||
{
|
|
||||||
Date now = new Date();
|
|
||||||
String timeString = String.valueOf(now.getHours()) + ":" + String.valueOf(now.getMinutes()) + ":" + String.valueOf(now.getSeconds());
|
|
||||||
Time nowTime = Time.valueOf(timeString);
|
|
||||||
Calendar calNow = Calendar.getInstance();
|
|
||||||
|
|
||||||
|
|
||||||
if(oneTrigger.getTimeFrame().getDayList().contains(calNow.get(Calendar.DAY_OF_WEEK)))
|
|
||||||
{
|
|
||||||
if(
|
|
||||||
// Regular case, start time is lower than end time
|
|
||||||
(
|
|
||||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
|
||||||
&&
|
|
||||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0
|
|
||||||
)
|
|
||||||
||
|
|
||||||
// Other case, start time higher than end time, timeframe goes over midnight
|
|
||||||
(
|
|
||||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0
|
|
||||||
&&
|
|
||||||
(Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
|
||||||
||
|
|
||||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0)
|
|
||||||
)
|
|
||||||
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// We are in the timeframe
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ") in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + "). Trigger of Rule " + this.getName() + " applies.", 3);
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 3);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the time. Trigger of Rule " + this.getName() + " doesn\'t apply..", 5);
|
|
||||||
if(!oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's what's specified. Trigger of Rule " + this.getName() + " applies.", 5);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "That's not what's specified. Trigger of Rule " + this.getName() + " doesn't apply.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "TimeFrame", "We're currently (" + calNow.getTime().toString() + ", Day: " + String.valueOf(calNow.get(Calendar.DAY_OF_WEEK)) + ") not in the specified TimeFrame (" + oneTrigger.getTimeFrame().toString() + ") because of the day. Trigger of Rule " + this.getName() + " doesn\'t apply.", 5);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.charging))
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.isDeviceCharging(context) == 0)
|
|
||||||
{
|
|
||||||
return false; // unknown charging state, can't activate rule under these conditions
|
|
||||||
}
|
|
||||||
else if(BatteryReceiver.isDeviceCharging(context) == 1)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter()) //rule says when charging, but we're currently discharging
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(BatteryReceiver.isDeviceCharging(context) == 2)
|
|
||||||
{
|
|
||||||
if(!oneTrigger.getTriggerParameter()) //rule says when discharging, but we're currently charging
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.usb_host_connection))
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.isUsbHostConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.batteryLevel))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(BatteryReceiver.getBatteryLevel() <= oneTrigger.getBatteryLevel())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryLowerThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBatteryLevel() >= oneTrigger.getBatteryLevel())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyBatteryHigherThan) + " " + String.valueOf(oneTrigger.getBatteryLevel()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.speed))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(LocationProvider.getSpeed() < oneTrigger.getSpeed())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreSlowerThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(LocationProvider.getSpeed() > oneTrigger.getSpeed())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWeAreFasterThan) + " " + String.valueOf(oneTrigger.getSpeed()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.noiseLevel))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
if(NoiseListener.getNoiseLevelDb() < oneTrigger.getNoiseLevelDb())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsQuieterThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(NoiseListener.getNoiseLevelDb() > oneTrigger.getNoiseLevelDb())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyItsLouderThan) + " " + String.valueOf(oneTrigger.getNoiseLevelDb()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.wifiConnection))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4);
|
|
||||||
if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected
|
|
||||||
{
|
|
||||||
if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4);
|
|
||||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2()))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name matches. Rule will apply.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "No wifi name specified, any will do.", 4);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi state not correct, demanded " + String.valueOf(oneTrigger.getTriggerParameter() + ", got " + String.valueOf(WifiBroadcastReceiver.lastConnectedState)), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.process_started_stopped))
|
|
||||||
{
|
|
||||||
boolean running = ProcessListener.getRunningApps().contains(oneTrigger.getProcessName());
|
|
||||||
|
|
||||||
if(running)
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is currently running.", 4);
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "App " + oneTrigger.getProcessName() + " is not running.", 4);
|
|
||||||
|
|
||||||
if(running != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger doesn't apply.", 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Miscellaneous.logEvent("i", "ProcessMonitoring", "Trigger applies.", 4);
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.airplaneMode))
|
|
||||||
{
|
|
||||||
if(ConnectivityReceiver.isAirplaneMode(context) != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.roaming))
|
|
||||||
{
|
|
||||||
if(ConnectivityReceiver.isRoaming(context) != oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall))
|
|
||||||
{
|
|
||||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
|
||||||
// state dir number
|
|
||||||
|
|
||||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2])))
|
|
||||||
{
|
|
||||||
//if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
|
||||||
if(
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING)
|
|
||||||
||
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK)
|
|
||||||
||
|
|
||||||
(elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if(
|
|
||||||
elements[1].equals(Trigger.triggerPhoneCallDirectionAny)
|
|
||||||
||
|
|
||||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1)
|
|
||||||
||
|
|
||||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Trigger conditions are met
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong direction. Demanded: " + String.valueOf(oneTrigger.getPhoneDirection()) + ", got: " + String.valueOf(PhoneStatusListener.getLastPhoneDirection()), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong call status. Demanded: " + String.valueOf(oneTrigger.getTriggerParameter()) + ", got: " + String.valueOf(PhoneStatusListener.isInACall()), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag))
|
|
||||||
{
|
|
||||||
if(NfcReceiver.lastReadLabel == null)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyNoTagLabel), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(!NfcReceiver.lastReadLabel.equals(oneTrigger.getNfcTagId()))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongTagLabel) + " " + NfcReceiver.lastReadLabel + " / " + oneTrigger.getNfcTagId(), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.activityDetection))
|
|
||||||
{
|
|
||||||
if(ActivityDetectionReceiver.getActivityDetectionLastResult() != null)
|
|
||||||
{
|
{
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for(DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
|
for (DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
|
||||||
{
|
{
|
||||||
if(oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType())
|
if (oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType())
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityNotPresent), ActivityDetectionReceiver.getDescription(oneTrigger.getActivityDetectionType())), 3);
|
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityNotPresent), ActivityDetectionReceiver.getDescription(oneTrigger.getActivityDetectionType())), 3);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
|
for (DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
|
||||||
{
|
{
|
||||||
if(oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType() && oneDetectedActivity.getConfidence() < Settings.activityDetectionRequiredProbability)
|
if (oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType() && oneDetectedActivity.getConfidence() < Settings.activityDetectionRequiredProbability)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityGivenButTooLowProbability), ActivityDetectionReceiver.getDescription(oneDetectedActivity.getType()), String.valueOf(oneDetectedActivity.getConfidence()), String.valueOf(Settings.activityDetectionRequiredProbability)), 3);
|
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyActivityGivenButTooLowProbability), ActivityDetectionReceiver.getDescription(oneDetectedActivity.getType()), String.valueOf(oneDetectedActivity.getConfidence()), String.valueOf(Settings.activityDetectionRequiredProbability)), 3);
|
||||||
return false;
|
return false;
|
||||||
@ -717,222 +387,12 @@ public class Rule implements Comparable<Rule>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.bluetoothConnection))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
|
|
||||||
|
|
||||||
if(oneTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// range
|
if (!oneTrigger.applies(null, context))
|
||||||
if(BluetoothReceiver.isAnyDeviceInRange() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(oneTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isAnyDeviceConnected() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// range
|
|
||||||
if(BluetoothReceiver.isAnyDeviceInRange() == oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getBluetoothDeviceAddress().length() > 0)
|
|
||||||
{
|
|
||||||
if(oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if((oneTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)))
|
|
||||||
{
|
|
||||||
if(BluetoothReceiver.isDeviceCurrentlyConnected(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// range
|
|
||||||
if(BluetoothReceiver.isDeviceInRange(BluetoothReceiver.getDeviceByAddress(oneTrigger.getBluetoothDeviceAddress())) != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyStateNotCorrect), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.headsetPlugged))
|
|
||||||
{
|
|
||||||
if(HeadphoneJackListener.isHeadsetConnected() != oneTrigger.getTriggerParameter())
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
if(oneTrigger.getHeadphoneType() != 2 && oneTrigger.getHeadphoneType() != HeadphoneJackListener.getHeadphoneType())
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), context.getResources().getString(R.string.ruleDoesntApplyWrongHeadphoneType), 3);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.notification))
|
|
||||||
{
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
|
|
||||||
{
|
|
||||||
String[] params = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
|
||||||
|
|
||||||
String myApp = params[0];
|
|
||||||
String myTitleDir = params[1];
|
|
||||||
String requiredTitle = params[2];
|
|
||||||
String myTextDir = params[3];
|
|
||||||
String requiredText;
|
|
||||||
if (params.length >= 5)
|
|
||||||
requiredText = params[4];
|
|
||||||
else
|
|
||||||
requiredText = "";
|
|
||||||
|
|
||||||
if(oneTrigger.getTriggerParameter())
|
|
||||||
{
|
|
||||||
// Check an active notification that is still there
|
|
||||||
|
|
||||||
boolean foundMatch = false;
|
|
||||||
|
|
||||||
for (StatusBarNotification sbn : NotificationListener.getInstance().getActiveNotifications())
|
|
||||||
{
|
|
||||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
|
||||||
{
|
|
||||||
String notificationApp = sbn.getPackageName();
|
|
||||||
String notificationTitle = null;
|
|
||||||
String notificationText = null;
|
|
||||||
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + notificationApp + ", title: " + notificationTitle + ", text: " + notificationText, 5);
|
|
||||||
|
|
||||||
if (!myApp.equals("-1"))
|
|
||||||
{
|
|
||||||
if (!notificationApp.equalsIgnoreCase(myApp))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(myApp.equals(BuildConfig.APPLICATION_ID))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
If there are multiple notifications ("stacked") title or text might be null:
|
|
||||||
https://stackoverflow.com/questions/28047767/notificationlistenerservice-not-reading-text-of-stacked-notifications
|
|
||||||
*/
|
|
||||||
|
|
||||||
Bundle extras = sbn.getNotification().extras;
|
|
||||||
|
|
||||||
// T I T L E
|
|
||||||
if (extras.containsKey(EXTRA_TITLE))
|
|
||||||
notificationTitle = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(requiredTitle))
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTitleDir, requiredTitle, notificationTitle))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required title for a notification trigger was not specified.", 5);
|
|
||||||
|
|
||||||
// T E X T
|
|
||||||
|
|
||||||
if (extras.containsKey(EXTRA_TEXT))
|
|
||||||
notificationText = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
|
||||||
|
|
||||||
if (!StringUtils.isEmpty(requiredText))
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTextDir, requiredText, notificationText))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5);
|
|
||||||
|
|
||||||
foundMatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!foundMatch)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// check a notification that is gone
|
|
||||||
|
|
||||||
if(NotificationListener.getLastNotification() != null)
|
|
||||||
{
|
|
||||||
if(!NotificationListener.getLastNotification().isCreated())
|
|
||||||
{
|
|
||||||
String app = NotificationListener.getLastNotification().getApp();
|
|
||||||
String title = NotificationListener.getLastNotification().getTitle();
|
|
||||||
String text = NotificationListener.getLastNotification().getText();
|
|
||||||
|
|
||||||
if (!myApp.equals("-1"))
|
|
||||||
{
|
|
||||||
if (!app.equalsIgnoreCase(myApp))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(myApp.equals(BuildConfig.APPLICATION_ID))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requiredTitle.length() > 0)
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTitleDir, title, requiredTitle))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requiredText.length() > 0)
|
|
||||||
{
|
|
||||||
if (!Miscellaneous.compare(myTextDir, text, requiredText))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -990,32 +450,6 @@ public class Rule implements Comparable<Rule>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean haveTriggersReallyChanged(Object triggeringObject)
|
|
||||||
{
|
|
||||||
boolean returnValue = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for(int i=0; i < triggerSet.size(); i++)
|
|
||||||
{
|
|
||||||
Trigger t = (Trigger) triggerSet.get(i);
|
|
||||||
|
|
||||||
if(t.hasStateRecentlyNotApplied(triggeringObject))
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("i", "Rule", "Rule \"" + getName() + "\" has trigger that flipped: " + t.toString(), 4);
|
|
||||||
returnValue = true; // only 1 trigger needs to have flipped recently
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("e", "Rule", "Error while checking if rule \"" + getName() + "\" haveTriggersReallyChanged(): " + Log.getStackTraceString(e), 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will activate the rule. Should be called by a separate execution thread
|
* Will activate the rule. Should be called by a separate execution thread
|
||||||
* @param automationService
|
* @param automationService
|
||||||
@ -1026,9 +460,9 @@ public class Rule implements Comparable<Rule>
|
|||||||
|
|
||||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||||
boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
|
|
||||||
|
|
||||||
if(notLastActive || force || doToggle || triggersApplyAnew)
|
//if(notLastActive || force || doToggle)
|
||||||
|
if(force || doToggle)
|
||||||
{
|
{
|
||||||
String message;
|
String message;
|
||||||
if(!doToggle)
|
if(!doToggle)
|
||||||
|
@ -264,7 +264,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
|||||||
|
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions())
|
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2);
|
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for entering POI " + this.getName() + ".", 2);
|
||||||
ruleCandidates.get(i).activate(parentService, false);
|
ruleCandidates.get(i).activate(parentService, false);
|
||||||
@ -296,7 +296,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
|||||||
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
|
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(parentService))
|
if(ruleCandidates.get(i).applies(parentService) && ruleCandidates.get(i).haveEnoughPermissions() && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2);
|
Miscellaneous.logEvent("i", "POI", "Rule " + ruleCandidates.get(i).getName() + " applies for leaving POI " + this.getName() + ".", 2);
|
||||||
ruleCandidates.get(i).activate(parentService, false);
|
ruleCandidates.get(i).activate(parentService, false);
|
||||||
|
@ -47,6 +47,7 @@ public class ReceiverCoordinator
|
|||||||
BatteryReceiver.class,
|
BatteryReceiver.class,
|
||||||
BluetoothReceiver.class,
|
BluetoothReceiver.class,
|
||||||
ConnectivityReceiver.class,
|
ConnectivityReceiver.class,
|
||||||
|
DevicePositionListener.class,
|
||||||
HeadphoneJackListener.class,
|
HeadphoneJackListener.class,
|
||||||
//NfcReceiver.class,
|
//NfcReceiver.class,
|
||||||
NoiseListener.class,
|
NoiseListener.class,
|
||||||
@ -57,13 +58,12 @@ public class ReceiverCoordinator
|
|||||||
}
|
}
|
||||||
catch (ClassNotFoundException e)
|
catch (ClassNotFoundException e)
|
||||||
{
|
{
|
||||||
// e.printStackTrace();
|
|
||||||
|
|
||||||
allImplementers = new Class[] {
|
allImplementers = new Class[] {
|
||||||
DateTimeListener.class,
|
DateTimeListener.class,
|
||||||
BatteryReceiver.class,
|
BatteryReceiver.class,
|
||||||
BluetoothReceiver.class,
|
BluetoothReceiver.class,
|
||||||
ConnectivityReceiver.class,
|
ConnectivityReceiver.class,
|
||||||
|
DevicePositionListener.class,
|
||||||
HeadphoneJackListener.class,
|
HeadphoneJackListener.class,
|
||||||
//NfcReceiver.class,
|
//NfcReceiver.class,
|
||||||
NoiseListener.class,
|
NoiseListener.class,
|
||||||
@ -167,6 +167,9 @@ public class ReceiverCoordinator
|
|||||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
|
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.process_started_stopped))
|
||||||
ProcessListener.startProcessListener(AutomationService.getInstance());
|
ProcessListener.startProcessListener(AutomationService.getInstance());
|
||||||
|
|
||||||
|
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.devicePosition))
|
||||||
|
DevicePositionListener.getInstance().startListener(AutomationService.getInstance());
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
|
Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath);
|
||||||
|
@ -31,103 +31,99 @@ import java.util.ArrayList;
|
|||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
|
||||||
public class Trigger
|
public class Trigger
|
||||||
{
|
{
|
||||||
Rule parentRule = null;
|
Rule parentRule = null;
|
||||||
boolean hasFlipped = false;
|
Calendar lastTimeNotApplied = null;
|
||||||
|
|
||||||
public boolean getHasFlipped()
|
|
||||||
{
|
|
||||||
return hasFlipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHasFlipped(boolean hasFlipped)
|
|
||||||
{
|
|
||||||
this.hasFlipped = hasFlipped;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean applies(Object triggeringObject, Context context)
|
public boolean applies(Object triggeringObject, Context context)
|
||||||
{
|
{
|
||||||
|
boolean result = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch(this.getTriggerType())
|
switch(this.getTriggerType())
|
||||||
{
|
{
|
||||||
case timeFrame:
|
case timeFrame:
|
||||||
if(!checkDateTime(triggeringObject, false))
|
if(!checkDateTime(triggeringObject, false))
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case pointOfInterest:
|
case pointOfInterest:
|
||||||
if(!checkLocation())
|
if(!checkLocation())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case charging:
|
case charging:
|
||||||
if(!checkCharging())
|
if(!checkCharging())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case usb_host_connection:
|
case usb_host_connection:
|
||||||
if(!checkUsbHostConnection())
|
if(!checkUsbHostConnection())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case batteryLevel:
|
case batteryLevel:
|
||||||
if(!checkBatteryLevel())
|
if(!checkBatteryLevel())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case speed:
|
case speed:
|
||||||
if(!checkSpeed())
|
if(!checkSpeed())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case noiseLevel:
|
case noiseLevel:
|
||||||
if(!checkNoiseLevel())
|
if(!checkNoiseLevel())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case wifiConnection:
|
case wifiConnection:
|
||||||
if(!checkWifiConnection())
|
if(!checkWifiConnection())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case process_started_stopped:
|
case process_started_stopped:
|
||||||
if(!checkProcess())
|
if(!checkProcess())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case airplaneMode:
|
case airplaneMode:
|
||||||
if(!checkAirplaneMode())
|
if(!checkAirplaneMode())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case roaming:
|
case roaming:
|
||||||
if(!checkRoaming())
|
if(!checkRoaming())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case phoneCall:
|
case phoneCall:
|
||||||
if(!checkPhoneCall())
|
if(!checkPhoneCall())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case nfcTag:
|
case nfcTag:
|
||||||
if(!checkNfc())
|
if(!checkNfc())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case bluetoothConnection:
|
case bluetoothConnection:
|
||||||
if(!checkBluetooth())
|
if(!checkBluetooth())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case headsetPlugged:
|
case headsetPlugged:
|
||||||
if(!checkHeadsetPlugged())
|
if(!checkHeadsetPlugged())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
case notification:
|
case notification:
|
||||||
if(!checkNotification())
|
if(!checkNotification())
|
||||||
return false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
|
case devicePosition:
|
||||||
|
and others
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.getParentRule().toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1);
|
Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.getParentRule().toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1);
|
||||||
return false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!result)
|
||||||
|
lastTimeNotApplied = Calendar.getInstance();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean checkNotification()
|
boolean checkNotification()
|
||||||
@ -623,31 +619,19 @@ public class Trigger
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasStateRecentlyNotApplied(Object triggeringObject)
|
public boolean hasStateNotAppliedSinceLastRuleExecution()
|
||||||
{
|
{
|
||||||
// nur mit einem Trigger?
|
if(getParentRule().getLastExecution() == null)
|
||||||
|
return true;
|
||||||
// door -> was state different in previous step
|
else if(lastTimeNotApplied != null)
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
switch(getTriggerType())
|
if(lastTimeNotApplied.getTimeInMillis() > getParentRule().getLastExecution().getTimeInMillis())
|
||||||
{
|
{
|
||||||
case timeFrame:
|
|
||||||
if(!checkDateTime(triggeringObject, true))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
Miscellaneous.logEvent("e", "Trigger", "Error while checking if rule " + getParentRule().getName() + " applies. Error occured in trigger " + this.getParentRule().toString() + "." + Miscellaneous.lineSeparator + Log.getStackTraceString(e), 1);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean checkCharging()
|
boolean checkCharging()
|
||||||
|
@ -201,7 +201,7 @@ public class LocationProvider
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesBySpeed();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesBySpeed();
|
||||||
for (Rule oneRule : ruleCandidates)
|
for (Rule oneRule : ruleCandidates)
|
||||||
{
|
{
|
||||||
if (oneRule.applies(this.getParentService()))
|
if (oneRule.applies(this.getParentService()) && oneRule.hasNotAppliedSinceLastExecution())
|
||||||
oneRule.activate(getParentService(), false);
|
oneRule.activate(getParentService(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,7 +147,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
|
||||||
for(Rule oneRule : ruleCandidates)
|
for(Rule oneRule : ruleCandidates)
|
||||||
{
|
{
|
||||||
if(oneRule.applies(automationServiceInstance))
|
if(oneRule.applies(automationServiceInstance) && oneRule.hasNotAppliedSinceLastExecution())
|
||||||
oneRule.activate(automationServiceInstance, false);
|
oneRule.activate(automationServiceInstance, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(true);
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(context))
|
if(ruleCandidates.get(i).applies(context) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBatteryLevel();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBatteryLevel();
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(context))
|
if(ruleCandidates.get(i).applies(context) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByCharging(false);
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(context))
|
if(ruleCandidates.get(i).applies(context) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
|
||||||
for(Rule oneRule : ruleCandidates)
|
for(Rule oneRule : ruleCandidates)
|
||||||
{
|
{
|
||||||
if(oneRule.applies(context))
|
if(oneRule.applies(context) && oneRule.hasNotAppliedSinceLastExecution())
|
||||||
oneRule.activate(automationServiceRef, false);
|
oneRule.activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
|
||||||
for(Rule oneRule : ruleCandidates)
|
for(Rule oneRule : ruleCandidates)
|
||||||
{
|
{
|
||||||
if(oneRule.applies(context))
|
if(oneRule.applies(context) && oneRule.hasNotAppliedSinceLastExecution())
|
||||||
oneRule.activate(automationServiceRef, false);
|
oneRule.activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection();
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(AutomationService.getInstance()))
|
if(ruleCandidates.get(i).applies(AutomationService.getInstance()) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(automationServiceRef))
|
if(ruleCandidates.get(i).applies(automationServiceRef) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(automationServiceRef))
|
if(ruleCandidates.get(i).applies(automationServiceRef) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationServiceRef, false);
|
ruleCandidates.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
|
|||||||
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
|
ArrayList<Rule> allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
|
||||||
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
|
for(int i=0; i<allRulesWithNowInTimeFrame.size(); i++)
|
||||||
{
|
{
|
||||||
if(allRulesWithNowInTimeFrame.get(i).applies(context))
|
if(allRulesWithNowInTimeFrame.get(i).applies(context) && allRulesWithNowInTimeFrame.get(i).hasNotAppliedSinceLastExecution())
|
||||||
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
|
allRulesWithNowInTimeFrame.get(i).activate(automationServiceRef, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +72,8 @@ public class DevicePositionListener implements SensorEventListener, AutomationLi
|
|||||||
|
|
||||||
public void stopSensorFromConfigActivity()
|
public void stopSensorFromConfigActivity()
|
||||||
{
|
{
|
||||||
|
activityManageTriggerDevicePositionInstance = null;
|
||||||
|
|
||||||
if(isRunning)
|
if(isRunning)
|
||||||
{
|
{
|
||||||
if(!Rule.isAnyRuleUsing(Trigger.Trigger_Enum.devicePosition))
|
if(!Rule.isAnyRuleUsing(Trigger.Trigger_Enum.devicePosition))
|
||||||
@ -127,7 +129,7 @@ public class DevicePositionListener implements SensorEventListener, AutomationLi
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.devicePosition);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.devicePosition);
|
||||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if (ruleCandidates.get(i).applies(Miscellaneous.getAnyContext()))
|
if (ruleCandidates.get(i).applies(Miscellaneous.getAnyContext()) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(context))
|
if(ruleCandidates.get(i).applies(context) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ public class NfcReceiver
|
|||||||
ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidatesByNfc();
|
ArrayList<Rule> allRulesWithNfcTags = Rule.findRuleCandidatesByNfc();
|
||||||
for(int i=0; i<allRulesWithNfcTags.size(); i++)
|
for(int i=0; i<allRulesWithNfcTags.size(); i++)
|
||||||
{
|
{
|
||||||
if(allRulesWithNfcTags.get(i).applies(asInstance))
|
if(allRulesWithNfcTags.get(i).applies(asInstance) && allRulesWithNfcTags.get(i).hasNotAppliedSinceLastExecution())
|
||||||
allRulesWithNfcTags.get(i).activate(asInstance, false);
|
allRulesWithNfcTags.get(i).activate(asInstance, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class NoiseListener implements AutomationListenerInterface
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByNoiseLevel();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByNoiseLevel();
|
||||||
for(Rule oneRule : ruleCandidates)
|
for(Rule oneRule : ruleCandidates)
|
||||||
{
|
{
|
||||||
if(oneRule.applies(automationService))
|
if(oneRule.applies(automationService) && oneRule.hasNotAppliedSinceLastExecution())
|
||||||
oneRule.activate(automationService, false);
|
oneRule.activate(automationService, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ public class NotificationListener extends NotificationListenerService
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
|
||||||
for (int i = 0; i < ruleCandidates.size(); i++)
|
for (int i = 0; i < ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if (ruleCandidates.get(i).applies(NotificationListener.this))
|
if (ruleCandidates.get(i).applies(NotificationListener.this) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
ruleCandidates.get(i).activate(AutomationService.getInstance(), false);
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
@ -114,7 +114,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
|||||||
{
|
{
|
||||||
AutomationService asInstance = AutomationService.getInstance();
|
AutomationService asInstance = AutomationService.getInstance();
|
||||||
if(asInstance != null)
|
if(asInstance != null)
|
||||||
if(ruleCandidates.get(i).applies(asInstance))
|
if(ruleCandidates.get(i).applies(asInstance) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(asInstance, false);
|
ruleCandidates.get(i).activate(asInstance, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
|||||||
{
|
{
|
||||||
AutomationService asInstance = AutomationService.getInstance();
|
AutomationService asInstance = AutomationService.getInstance();
|
||||||
if (asInstance != null)
|
if (asInstance != null)
|
||||||
if (ruleCandidates.get(i).applies(asInstance))
|
if (ruleCandidates.get(i).applies(asInstance) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(asInstance, false);
|
ruleCandidates.get(i).activate(asInstance, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
|
|||||||
{
|
{
|
||||||
AutomationService asInstance = AutomationService.getInstance();
|
AutomationService asInstance = AutomationService.getInstance();
|
||||||
if(asInstance != null)
|
if(asInstance != null)
|
||||||
if(ruleCandidates.get(i).applies(asInstance))
|
if(ruleCandidates.get(i).applies(asInstance) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(asInstance, false);
|
ruleCandidates.get(i).activate(asInstance, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class ProcessListener implements AutomationListenerInterface
|
|||||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByProcess();
|
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByProcess();
|
||||||
for(int i=0; i<ruleCandidates.size(); i++)
|
for(int i=0; i<ruleCandidates.size(); i++)
|
||||||
{
|
{
|
||||||
if(ruleCandidates.get(i).applies(automationService))
|
if(ruleCandidates.get(i).applies(automationService) && ruleCandidates.get(i).hasNotAppliedSinceLastExecution())
|
||||||
ruleCandidates.get(i).activate(automationService, false);
|
ruleCandidates.get(i).activate(automationService, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user