Hello everyone.
I'd like to share a flow and widget I've made to make checking which trigger started a flow (with condition expression) easier . The ideea is to get the list of triggers in the current flow, to copy the one you want in the expression (trigger==...). This feature has already been demanded and Martin is probably implementing it already. In the meantime my flow should do that. It's a rather minor feature that needed lots of retries for me to implemnt.
General ideea is:
1.detect opening flow activity> get current flow name >export the flow to a temp xml > use xpath to get current flow triggers and store them in a glo var global_triggers
2.detect when opening condition expression and display a little widget > click the widget and get the list of triggers, click on one and paste it in the script window.
I've tried multiple approaches before getting it right
tried to read the whole xml flows file (fails if > 1mb)
tried java functions but automagic loops are limited to 10000 iterations, it was getting VERY slow
tried using xmlpullparser...didn't get very far
finally tge solution was exporting the flow and parsing it with xpath
one limitation is when opening flow activity if you have the search bbox showing it can't get the flow name, so that must be closed.
Anyways, hope someone can test it and tell me what they think
Triggers select helper
Moderator: Martin
Re: Triggers select helper
I take another approach and have changed it again to faster one. But required the phone to have additional button at the navbar for maximum efficiency.
Your shared xml only contain widget, not the flow. Hence nothing to test. But as your explanation :
1. it is not preferred to use UI event to detect the flow opening or the condition expression; it is quite slow. I used to use the UI event too, but at new phone, the delay can be up to 800-1200 ms, which is quite slow. So I change it to definite shortcut and use Control UI to loop wait with lower latency (100 ms)
2. To read file bigger than 1 MB, use
execute command : cat /storage/emulated/0/Automagic/flows.xml
Parse the {stdout}. I face the same problem too in my automagic statistic flow.
3. You can loop more than 10000 by using nested loop. Example, you can loop for 10000 and another 10000 in the nested loop, total 100 million loops. But generally not advised to do so, it can loop to a very long time, if you have long function again at the nested level. The loop will stall all other script/expression, as Automagic implement global lock to prevent race condition. Besides, each nested loop add additional overhead. It is better to loop 1000, rather than loop nested 10-10-10.
4. Automagic's Xpath is quite slow. I don't know if Xpath is slow in general or only in Automagic. I would prefer to use regex, much faster. Approx half year ago, the same flows.xml takes 5-10 seconds to process on Xpath, but only below 500 ms consistently using unoptimized regex. That's why I tend to use regex, even when parsing xml. The speed is unsurpassed till date. findAll() is one the most powerful function that I use frequently.
My trigger to expression works by using usual shortcut, can be mapped to navbar, widget, quick setting or other exotic trigger such as shake, magnet, proximity. It mostly contains Control UI to loop wait and retrieve the trigger name. Then create a expression to check triggers. It is very hard to share, as I have mixed it with other flow too. I need to show how to use it and the logic behind it. Because control UI need adjustment to make it works at different phone.
I am actually working on the last piece of the automagic statistic flow before sharing it (this contains how to parse the flows.xml). It has one of the longest scripting flow I've ever made. But always distracted by other flow. I have finished probably 7 flows and I haven't started to work on the last piece.
Your shared xml only contain widget, not the flow. Hence nothing to test. But as your explanation :
1. it is not preferred to use UI event to detect the flow opening or the condition expression; it is quite slow. I used to use the UI event too, but at new phone, the delay can be up to 800-1200 ms, which is quite slow. So I change it to definite shortcut and use Control UI to loop wait with lower latency (100 ms)
2. To read file bigger than 1 MB, use
execute command : cat /storage/emulated/0/Automagic/flows.xml
Parse the {stdout}. I face the same problem too in my automagic statistic flow.
3. You can loop more than 10000 by using nested loop. Example, you can loop for 10000 and another 10000 in the nested loop, total 100 million loops. But generally not advised to do so, it can loop to a very long time, if you have long function again at the nested level. The loop will stall all other script/expression, as Automagic implement global lock to prevent race condition. Besides, each nested loop add additional overhead. It is better to loop 1000, rather than loop nested 10-10-10.
4. Automagic's Xpath is quite slow. I don't know if Xpath is slow in general or only in Automagic. I would prefer to use regex, much faster. Approx half year ago, the same flows.xml takes 5-10 seconds to process on Xpath, but only below 500 ms consistently using unoptimized regex. That's why I tend to use regex, even when parsing xml. The speed is unsurpassed till date. findAll() is one the most powerful function that I use frequently.
My trigger to expression works by using usual shortcut, can be mapped to navbar, widget, quick setting or other exotic trigger such as shake, magnet, proximity. It mostly contains Control UI to loop wait and retrieve the trigger name. Then create a expression to check triggers. It is very hard to share, as I have mixed it with other flow too. I need to show how to use it and the logic behind it. Because control UI need adjustment to make it works at different phone.
I am actually working on the last piece of the automagic statistic flow before sharing it (this contains how to parse the flows.xml). It has one of the longest scripting flow I've ever made. But always distracted by other flow. I have finished probably 7 flows and I haven't started to work on the last piece.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.
Re: Triggers select helper
Hi Desmanto, I shared the flow finally
1. what exactly do you mean wait/loop? my trigger is activity started with usave statistics and it works fine for now. control ui is used once with getTextInActiveWindow, also good.
2. do you actually process your whole flows. xml? mine is 1.3mb 21600 lines, your probably is alot longer. do you get good performance using findAll with all that input? didn't try but should be nice since I also love regex.
The flow is fast enough as it is, the problem is I can't always get the current open flow name since it is blocked by 'find' window.
Try it out and tell me what you think
1. what exactly do you mean wait/loop? my trigger is activity started with usave statistics and it works fine for now. control ui is used once with getTextInActiveWindow, also good.
2. do you actually process your whole flows. xml? mine is 1.3mb 21600 lines, your probably is alot longer. do you get good performance using findAll with all that input? didn't try but should be nice since I also love regex.
The flow is fast enough as it is, the problem is I can't always get the current open flow name since it is blocked by 'find' window.
Try it out and tell me what you think
Re: Triggers select helper
I have tested it. Surprised that the Activity Started still work at RR 6.2 Oreo 8.1. It is the same as App Task started, same up to 1200 ms delay, except it can dig into activity too. I should try this too in my other flow.
Your concept is correct, but there is a more efficient way to do it.
- Using Automagic flow activity as trigger will slow down the whole flow editing experience, you don't want that to happen. Because we open flow every time, but not always want to create trigger expression checker
- Same with show widget at expression, not all expression are dealing with this, so it will distract a lot
- You don't have to query available trigger from flows.xml, it is available directly in the trigger selection. When you tap the edit icon, there are 2 triggers, you can use getTextInWindow() from here and parse the text (which is what I do). But if your trigger only one, the edit icon will bring you directly to the trigger. You can still retrieve the name by getting the trigger name
- You can add another list "Widget Click" to the choice
- Yours only use single choice, while sometimes we need multi triggers check.
Mine doesn't use glovar, clipboard or query the xml at at all. All is done directly on that flow. Your XPath only query one element from xml. I use looped XPath to query ALL elements in my Automagic statistic flow, hence processing almost everything. (not for this trigger select helper flow) The difference is huge, since at that time my flows.xml is near to 1 MB. I just realize currently it is already 1,54 MB, 28000 lines. 50+ active flows from 163. There are probably 30-40 not my flows (just like I import yours).
Mine doesn't use glovar, clipboard or query the xml at at all. All is done directly on that flow. Your XPath only query one element from xml. I use looped XPath to query ALL elements in my Automagic statistic flow, hence processing almost everything. (not for this trigger select helper flow) The difference is huge, since at that time my flows.xml is near to 1 MB. I just realize currently it is already 1,54 MB, 28000 lines. 50+ active flows from 163. There are probably 30-40 not my flows (just like I import yours).
My old Trigger to expression concept :
1. UI event detect the "Select Trigger" when you tap the edit icon.
2. Show a widget, which when you tap will query the text and parse the trigger name.
3. Add, "Manual" and "Widget Click", Put into input dialog - multiple choice.
4. After selecting, create the variable to store the expression script. If single trigger choosen, use "==". If multiple, use containsElement()
5. Then Control UI get into loop wait state. It waits us to drag the + button to create a new element, The script waits for "Add…" at the title. If 3 seconds passed without the "Add…", it fails and go to the exception (timer/0 result in error), catch it. This is the example of the waiting script
6. The next CUI script after the loop wait is CUI script to create new condition > expression, set the text field to the expression script created. Done.
I have refined it since then, because UI event takes up to 1200 ms. Not all the time I tap edit icon is to create the expression. And the flow won't work on single trigger flow. Therefore, I remove the UI event and change it to shortcut. The shortcut trigger another loop wait to detect the trigger name, whether it is multiple or single. Hence I don't need widget anymore. The rest is almost the same.
The basic flow only contains 2 Control UI, 1 Input dialog multiple choice and another Notification on screen. If you are interested, I will split it out later to a separate flow. I actually plan to share after I remake another part for the favourite elements. I have reuse the same concept in several other usage.
Your concept is correct, but there is a more efficient way to do it.
- Using Automagic flow activity as trigger will slow down the whole flow editing experience, you don't want that to happen. Because we open flow every time, but not always want to create trigger expression checker
- Same with show widget at expression, not all expression are dealing with this, so it will distract a lot
- You don't have to query available trigger from flows.xml, it is available directly in the trigger selection. When you tap the edit icon, there are 2 triggers, you can use getTextInWindow() from here and parse the text (which is what I do). But if your trigger only one, the edit icon will bring you directly to the trigger. You can still retrieve the name by getting the trigger name
- You can add another list "Widget Click" to the choice
- Yours only use single choice, while sometimes we need multi triggers check.
Mine doesn't use glovar, clipboard or query the xml at at all. All is done directly on that flow. Your XPath only query one element from xml. I use looped XPath to query ALL elements in my Automagic statistic flow, hence processing almost everything. (not for this trigger select helper flow) The difference is huge, since at that time my flows.xml is near to 1 MB. I just realize currently it is already 1,54 MB, 28000 lines. 50+ active flows from 163. There are probably 30-40 not my flows (just like I import yours).
Mine doesn't use glovar, clipboard or query the xml at at all. All is done directly on that flow. Your XPath only query one element from xml. I use looped XPath to query ALL elements in my Automagic statistic flow, hence processing almost everything. (not for this trigger select helper flow) The difference is huge, since at that time my flows.xml is near to 1 MB. I just realize currently it is already 1,54 MB, 28000 lines. 50+ active flows from 163. There are probably 30-40 not my flows (just like I import yours).
My old Trigger to expression concept :
1. UI event detect the "Select Trigger" when you tap the edit icon.
2. Show a widget, which when you tap will query the text and parse the trigger name.
3. Add, "Manual" and "Widget Click", Put into input dialog - multiple choice.
4. After selecting, create the variable to store the expression script. If single trigger choosen, use "==". If multiple, use containsElement()
5. Then Control UI get into loop wait state. It waits us to drag the + button to create a new element, The script waits for "Add…" at the title. If 3 seconds passed without the "Add…", it fails and go to the exception (timer/0 result in error), catch it. This is the example of the waiting script
Code: Select all
//waiting for timer
timer = 0;
while(getTextById("android:id/alertTitle") != "Add…")
{
if(timer <= 3000)
{
timer = timer + 200;
sleep(200);
}
else
{
msg = "Please add new element within 3 seconds!";
timer/0;
}
}
I have refined it since then, because UI event takes up to 1200 ms. Not all the time I tap edit icon is to create the expression. And the flow won't work on single trigger flow. Therefore, I remove the UI event and change it to shortcut. The shortcut trigger another loop wait to detect the trigger name, whether it is multiple or single. Hence I don't need widget anymore. The rest is almost the same.
The basic flow only contains 2 Control UI, 1 Input dialog multiple choice and another Notification on screen. If you are interested, I will split it out later to a separate flow. I actually plan to share after I remake another part for the favourite elements. I have reuse the same concept in several other usage.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.