diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index f9040a53..cc7935bd 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,6 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -12,6 +23,6 @@
-
+
\ No newline at end of file
diff --git a/app/src/apkFlavor/java/com/jens/automation2/Rule.java b/app/src/apkFlavor/java/com/jens/automation2/Rule.java
index bd5ee2b6..1120377d 100644
--- a/app/src/apkFlavor/java/com/jens/automation2/Rule.java
+++ b/app/src/apkFlavor/java/com/jens/automation2/Rule.java
@@ -1,44 +1,22 @@
package com.jens.automation2;
+import static com.jens.automation2.Trigger.triggerParameter2Split;
+
import android.annotation.SuppressLint;
-import android.app.Notification;
-import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
import android.os.Looper;
-import android.os.Parcelable;
-import android.service.notification.StatusBarNotification;
-import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
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.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.util.ArrayList;
import java.util.Calendar;
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
{
@@ -356,6 +334,17 @@ public class Rule implements Comparable
return false;
}
+
+ public boolean hasNotAppliedSinceLastExecution()
+ {
+ for(Trigger oneTrigger : this.getTriggerSet())
+ {
+ if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
+ return true;
+ }
+
+ return false;
+ }
public boolean applies(Context context)
{
@@ -461,32 +450,6 @@ public class Rule implements Comparable
}
}
- 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
* @param automationService
@@ -497,9 +460,9 @@ public class Rule implements Comparable
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggable;
- boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
- if(notLastActive || force || doToggle || triggersApplyAnew)
+ //if(notLastActive || force || doToggle)
+ if(force || doToggle)
{
String message;
if(!doToggle)
diff --git a/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java b/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java
index 90ca7e6c..f20ec687 100644
--- a/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java
+++ b/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java
@@ -294,7 +294,7 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
ArrayList allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
for(int i=0; i
{
@@ -357,6 +341,17 @@ public class Rule implements Comparable
return false;
}
+
+ public boolean hasNotAppliedSinceLastExecution()
+ {
+ for(Trigger oneTrigger : this.getTriggerSet())
+ {
+ if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
+ return true;
+ }
+
+ return false;
+ }
public boolean applies(Context context)
{
@@ -370,538 +365,8 @@ public class Rule implements Comparable
{
for(Trigger oneTrigger : this.getTriggerSet())
{
- if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.pointOfInterest))
- {
- // 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;
- }
- }
- 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(""))
- {
- 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(""))
- {
- 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;
- }
- }
- }
- }
+ if (!oneTrigger.applies(null, context))
+ return false;
}
return true;
@@ -960,32 +425,6 @@ public class Rule implements Comparable
}
}
- 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
* @param automationService
@@ -996,9 +435,9 @@ public class Rule implements Comparable
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggable;
- boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
- if(notLastActive || force || doToggle || triggersApplyAnew)
+ //if(notLastActive || force || doToggle)
+ if(force || doToggle)
{
String message;
if(!doToggle)
diff --git a/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java b/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java
index e541dc72..4a4fa69b 100644
--- a/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java
+++ b/app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java
@@ -1,46 +1,22 @@
package com.jens.automation2;
+import static com.jens.automation2.Trigger.triggerParameter2Split;
+
import android.annotation.SuppressLint;
-import android.app.Notification;
-import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.os.AsyncTask;
-import android.os.Build;
-import android.os.Bundle;
import android.os.Looper;
-import android.os.Parcelable;
-import android.service.notification.StatusBarNotification;
-import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
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.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.util.ArrayList;
import java.util.Calendar;
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
{
@@ -358,6 +334,17 @@ public class Rule implements Comparable
return false;
}
+
+ public boolean hasNotAppliedSinceLastExecution()
+ {
+ for(Trigger oneTrigger : this.getTriggerSet())
+ {
+ if (oneTrigger.hasStateNotAppliedSinceLastRuleExecution())
+ return true;
+ }
+
+ return false;
+ }
public boolean applies(Context context)
{
@@ -371,344 +358,27 @@ public class Rule implements Comparable
{
for(Trigger oneTrigger : this.getTriggerSet())
{
- if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.pointOfInterest))
+ if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.activityDetection))
{
- // 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;
- }
- }
- 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)
+ if (ActivityDetectionReceiver.getActivityDetectionLastResult() != null)
{
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;
}
- 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);
return false;
}
else
{
- for(DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
- {
- if(oneDetectedActivity.getType() == oneTrigger.getActivityDetectionType() && oneDetectedActivity.getConfidence() < Settings.activityDetectionRequiredProbability)
+ for (DetectedActivity oneDetectedActivity : ActivityDetectionReceiver.getActivityDetectionLastResult().getProbableActivities())
+ {
+ 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);
return false;
@@ -717,220 +387,10 @@ public class Rule implements Comparable
}
}
}
- else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.bluetoothConnection))
+ else
{
- Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for bluetooth...", 4);
-
- if(oneTrigger.getBluetoothDeviceAddress().equals(""))
- {
- 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(""))
- {
- 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);
+ if (!oneTrigger.applies(null, context))
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;
- }
- }
- }
}
}
@@ -990,32 +450,6 @@ public class Rule implements Comparable
}
}
- 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
* @param automationService
@@ -1026,9 +460,9 @@ public class Rule implements Comparable
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
boolean doToggle = ruleToggle && isActuallyToggable;
- boolean triggersApplyAnew = haveTriggersReallyChanged(new Date());
- if(notLastActive || force || doToggle || triggersApplyAnew)
+ //if(notLastActive || force || doToggle)
+ if(force || doToggle)
{
String message;
if(!doToggle)
diff --git a/app/src/main/java/com/jens/automation2/PointOfInterest.java b/app/src/main/java/com/jens/automation2/PointOfInterest.java
index 7a42031a..edf39597 100644
--- a/app/src/main/java/com/jens/automation2/PointOfInterest.java
+++ b/app/src/main/java/com/jens/automation2/PointOfInterest.java
@@ -264,7 +264,7 @@ public class PointOfInterest implements Comparable
for(int i=0; i
Miscellaneous.logEvent("i", "POI", "POI " + this.getName() + " found in " + ruleCandidates.size() + " rule(s).", 2);
for(int i=0; i was state different in previous step
-
- try
- {
- switch(getTriggerType())
- {
- case timeFrame:
- if(!checkDateTime(triggeringObject, true))
- return false;
- break;
- default:
- break;
- }
-
+ if(getParentRule().getLastExecution() == null)
return true;
- }
- catch(Exception e)
+ else if(lastTimeNotApplied != null)
{
- 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;
+ if(lastTimeNotApplied.getTimeInMillis() > getParentRule().getLastExecution().getTimeInMillis())
+ {
+ return true;
+ }
}
+
+ return false;
}
boolean checkCharging()
diff --git a/app/src/main/java/com/jens/automation2/location/LocationProvider.java b/app/src/main/java/com/jens/automation2/location/LocationProvider.java
index 8a2956ec..d50ac70b 100644
--- a/app/src/main/java/com/jens/automation2/location/LocationProvider.java
+++ b/app/src/main/java/com/jens/automation2/location/LocationProvider.java
@@ -201,7 +201,7 @@ public class LocationProvider
ArrayList ruleCandidates = Rule.findRuleCandidatesBySpeed();
for (Rule oneRule : ruleCandidates)
{
- if (oneRule.applies(this.getParentService()))
+ if (oneRule.applies(this.getParentService()) && oneRule.hasNotAppliedSinceLastExecution())
oneRule.activate(getParentService(), false);
}
}
diff --git a/app/src/main/java/com/jens/automation2/location/WifiBroadcastReceiver.java b/app/src/main/java/com/jens/automation2/location/WifiBroadcastReceiver.java
index c2b2ea53..b8a9a8c7 100644
--- a/app/src/main/java/com/jens/automation2/location/WifiBroadcastReceiver.java
+++ b/app/src/main/java/com/jens/automation2/location/WifiBroadcastReceiver.java
@@ -147,7 +147,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
ArrayList ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
for(Rule oneRule : ruleCandidates)
{
- if(oneRule.applies(automationServiceInstance))
+ if(oneRule.applies(automationServiceInstance) && oneRule.hasNotAppliedSinceLastExecution())
oneRule.activate(automationServiceInstance, false);
}
}
diff --git a/app/src/main/java/com/jens/automation2/receivers/BatteryReceiver.java b/app/src/main/java/com/jens/automation2/receivers/BatteryReceiver.java
index 0d75214d..9d2de54e 100644
--- a/app/src/main/java/com/jens/automation2/receivers/BatteryReceiver.java
+++ b/app/src/main/java/com/jens/automation2/receivers/BatteryReceiver.java
@@ -206,7 +206,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
ArrayList ruleCandidates = Rule.findRuleCandidatesByCharging(true);
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByBatteryLevel();
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByCharging(false);
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByUsbHost(true);
for(Rule oneRule : ruleCandidates)
{
- if(oneRule.applies(context))
+ if(oneRule.applies(context) && oneRule.hasNotAppliedSinceLastExecution())
oneRule.activate(automationServiceRef, false);
}
@@ -278,7 +278,7 @@ public class BatteryReceiver extends BroadcastReceiver implements AutomationList
ArrayList ruleCandidates = Rule.findRuleCandidatesByUsbHost(false);
for(Rule oneRule : ruleCandidates)
{
- if(oneRule.applies(context))
+ if(oneRule.applies(context) && oneRule.hasNotAppliedSinceLastExecution())
oneRule.activate(automationServiceRef, false);
}
}
diff --git a/app/src/main/java/com/jens/automation2/receivers/BluetoothReceiver.java b/app/src/main/java/com/jens/automation2/receivers/BluetoothReceiver.java
index 0415c781..0abc46b9 100644
--- a/app/src/main/java/com/jens/automation2/receivers/BluetoothReceiver.java
+++ b/app/src/main/java/com/jens/automation2/receivers/BluetoothReceiver.java
@@ -127,7 +127,7 @@ public class BluetoothReceiver extends BroadcastReceiver implements AutomationLi
ArrayList ruleCandidates = Rule.findRuleCandidatesByBluetoothConnection();
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByAirplaneMode(isAirplaneMode);
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByRoaming(isRoaming);
for(int i=0; i allRulesWithNowInTimeFrame = Rule.findRuleCandidatesByTime(passTime);
for(int i=0; i ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.devicePosition);
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);
}
}
diff --git a/app/src/main/java/com/jens/automation2/receivers/HeadphoneJackListener.java b/app/src/main/java/com/jens/automation2/receivers/HeadphoneJackListener.java
index fc377183..807fcd41 100644
--- a/app/src/main/java/com/jens/automation2/receivers/HeadphoneJackListener.java
+++ b/app/src/main/java/com/jens/automation2/receivers/HeadphoneJackListener.java
@@ -77,7 +77,7 @@ public class HeadphoneJackListener extends BroadcastReceiver implements Automati
ArrayList ruleCandidates = Rule.findRuleCandidatesByHeadphoneJack(isHeadsetConnected());
for(int i=0; i allRulesWithNfcTags = Rule.findRuleCandidatesByNfc();
for(int i=0; i ruleCandidates = Rule.findRuleCandidatesByNoiseLevel();
for(Rule oneRule : ruleCandidates)
{
- if(oneRule.applies(automationService))
+ if(oneRule.applies(automationService) && oneRule.hasNotAppliedSinceLastExecution())
oneRule.activate(automationService, false);
}
}
diff --git a/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java b/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java
index 8daaf344..f3d97b06 100644
--- a/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java
+++ b/app/src/main/java/com/jens/automation2/receivers/NotificationListener.java
@@ -96,7 +96,7 @@ public class NotificationListener extends NotificationListenerService
ArrayList ruleCandidates = Rule.findRuleCandidates(Trigger.Trigger_Enum.notification);
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);
}
// }
diff --git a/app/src/main/java/com/jens/automation2/receivers/PhoneStatusListener.java b/app/src/main/java/com/jens/automation2/receivers/PhoneStatusListener.java
index ae67a2f8..9e9f4100 100644
--- a/app/src/main/java/com/jens/automation2/receivers/PhoneStatusListener.java
+++ b/app/src/main/java/com/jens/automation2/receivers/PhoneStatusListener.java
@@ -114,7 +114,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
AutomationService asInstance = AutomationService.getInstance();
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);
}
}
@@ -146,7 +146,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
AutomationService asInstance = AutomationService.getInstance();
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);
}
}
@@ -183,7 +183,7 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
AutomationService asInstance = AutomationService.getInstance();
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);
}
}
diff --git a/app/src/main/java/com/jens/automation2/receivers/ProcessListener.java b/app/src/main/java/com/jens/automation2/receivers/ProcessListener.java
index 42778dc6..4390ea0b 100644
--- a/app/src/main/java/com/jens/automation2/receivers/ProcessListener.java
+++ b/app/src/main/java/com/jens/automation2/receivers/ProcessListener.java
@@ -62,7 +62,7 @@ public class ProcessListener implements AutomationListenerInterface
ArrayList ruleCandidates = Rule.findRuleCandidatesByProcess();
for(int i=0; i