SD Maid v4.5.3 fixes a long standing issue regarding running apps detection.http://sdmaid.darken.eu/downloadhttp://sdmaid.darken.eu/changeloghttp://sdmaid.darken.eu/issues
If you care for a little bit of in-depth ramblings:
Story time, because this was an interesting one.
A user mailed me about SD Maid v4.5.0+ not detecting frozen apps correctly.
Although communication was a bit cumbersome (no common language, had to google translate), without him this problem would have likely gone unnoticed for quite a while.
Ok so the predicate is that frozen app detection doesn't work correctly. I wasn't too suprised by this because v4.5.0 changed a lot of AppControl code, so I just made a mistake... No problem, that's what betas are for, so lets reproduce this. I gathered a couple of devices and compared v4.4.1 against v4.5.0. Checked Pixel... no difference, checked Nexus9... no difference, checked a MotoG3... oh okay 1 app difference. That's at least something to work with. It's a system app, something OTA related.
I installed a dev version of v4.5.0 on it, still reproducable, so start the debugger and look deeper. Why does it not enter the code to check for frozen / force-stopped code? The app wasn't even checked for it's "frozen" (disabled) state (a change I made in v4.5.0+) because the application was running!? Checking the state in the debugger manually... it's disabled and running !? Wait what? It's either frozen or running... can't be both.
Alright, start ADB shell, check running processes manually, basically looks for that apps packagename in process infos. It's not running! Why does SD Maid think it's running?
So the bug is not with frozen apps or their detection it's with running apps detection.
So how does the current code detect running apps...
It's a main method with a fallback method. Fallback gets chosen when the main method returns no usable results. This isn't the case care here so the wrong data comes from the main method. Right the main method uses the linux applet "ps" to get a list of running processes including their process id, user id and process arguments. Then we get a list of installed apps and iterate the list, then for each installed app we get the user id and see if there is a process with the same user id. Sounds like sound logic to me... at least I thought so for probably a long time because this piece of code has existed since SD Maid v3...
Right so where is the flaw? Apps can share their user id... Oh it's so obvious... something something hindsight 20/20... So a process if the user id 1000 was running (common for the system itself and the case for our problem app from above), we would consider all apps with that user id as running... This also had a negative effect on other tools if they use the running apps data to skip operations on active apps. Ok now one can argue that shared user ids means shared access so skipping action based on that data would actually be more accurate, but in reality it didn't lead to the desired behavior and the chance for issues from it is negligble.
The solution is to determine running apps based on command argument output from "ps". In almost all cases the argument is the exact packagename, a bit of parsing/regex takes care of the rest. So I changed the code, installed and the missing frozen app on the MotoG was suddenly "Frozen" and no longer "Running", yay!
I still had some concerns over using the command argument from "ps", parsing always breaks with edge cases and I'm not sure how many there can be, because every device is different... We can't make it more relaxed because if we don't match the packagenames EXACTLY we get false positives again. A user id being just a number was much each to handle... Remember the "fallback" method from above? It's using different approaches to get the same data from the official Android API, lets just make it not a "fallback" option. Lets just take the data and merge it with the data from "ps" based on the process id. You may ask yourself why two methods in the first place? Not all ROMs give reliable data via the same methods.
To make issues such as this more obvious, e.g. an app both running and being frozen/force-stopped, I now don't make assumption, check both and display both if it happens, such that the error is also more obvious UI wise.
So that's the story of how running app detection was fixed. Have a nice sunday everyone!