While testing an Android box with Android 12 (model Mekotronics R58X, you can expect a review in the future), I came across two minor issues with Slideshow app that were connected to recent updates in Android 11 and 12. Below is a short, but quite technical summary of what caused the trouble and how it was solved.
App was not automatically started after remote update
It is possible to remotely update Slideshow app on rooted devices, without need for Mobile Device Management (MDM) or Google Play store. Slideshow uses special script for updating itself, which runs the APK installation and starts the app afterwards, something similar to this:
nohup sh -c '
pm install -d -r slideshow-android.apk;
sleep 2;
am start -n sk.mimac.slideshow/sk.mimac.slideshow.StartupActivity
' &>/dev/null 0<&-
Wrapping the entire script in nohup command and redirection of output to /dev/null is necessary because as soon as the update starts (with command pm install...
), the app is killed by Android system (as it is being updated at that moment). Without nohup, killing the parent process (Slideshow app) would also kill the child process (update script) and the app wouldn’t autostart after the update (with command am start...
). Nohup changes the parent process of the update script to the init process, so it is no longer directly connected to the app process.
However in Android 12 so-called phantom process killing was introduced. It doesn’t check what is the parent process of each process, but in which cgroup it is. As the nohup command doesn’t modify cgroup of the process, the update script is still running within the cgroup of the app and after the app process is killed (when the update is started), phantom process killing kills the update script as well. The result is that the updating is successful, but the app has to be started manually. Thanks to the extensive help of user agnostic-apollo in this Reddit thread, I was able to come up with a solution. The script first changes its cgroup (it can do it, as it is running as root on a rooted device), so there is no longer any connection to the app process. The result looks like this:
nohup sh -c '
files=(/sys/fs/cgroup/uid_0/pid_*);
echo $$ | tee ${files[0]}/cgroup.procs;
pm install -d -r slideshow-android.apk;
sleep 2
am start -n sk.mimac.slideshow/sk.mimac.slideshow.StartupActivity
' &>/dev/null 0<&-
This fix is already part of Slideshow version 4.0.0, so after updating from this version to a newer one on Android 12+, Slideshow should automatically start itself once again.
Dialog for granting storage permission was not opened automatically
In Android 11 Google changed how storage permissions for apps are handled. If an app wants to have access to all files in the internal storage, it has to ask the user to grant the permission and the user has to manually allow it (for example click a checkbox and confirm).
The dialog for this storage permissions can be opened by calling action ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION (as described in the official Android documentation). During first start of Slideshow app, if it detects that it is missing the permission for internal storage (result of call Environment.isExternalStorageManager()
is false), it displays user a notification dialog and then starts action ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION, which should display the Android permission dialog.
However on this particular Android box calling that action didn’t work, it returned an error that the action was not found. The only way was to manually navigate to Android settings – Apps – Slideshow – Permissions and allow storage access. I exchanged a couple of emails with Mekotronics support regarding this and while they were certainly trying to help, unfortunately their only solution was to install the app as a system app, in which case it receives all permissions automatically. Missing support for ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION is probably something originating in the Rockchip source code for the entire platform.
As we didn’t want to force Slideshow app as a system app (it has many other consequences), we decided to just notify users that the storage permission has to be granted manually. We are aware that it is not the best solution, but in the situation where the official Android documentation says one thing and the hardware manufacturer implements different thing, there are unfortunately no good solutions.