A Watchdog is a solution to recover the player from crashes. An application needs to register itself with the watchdog service and then periodically send messages to the service that it is alive. In case the watchdog service does not receive a keep-alive message within a stipulated time, the service attempts to reboot the device for a clean recovery (if it has the sufficient privileges) or restart the application.
Due to Android's architecture, rebooting the device requires that the application has system privileges. To do this, you need to sign the apk using the manufacturer's signing keys, otherwise watchdog will restart the player application and not reboot the device.
To access some of the privileged APIs of Android such as PowerManager or HDMIControlServices, you need to sign the the android apk using the manufacturer's keys.
You should have the android SDK installed, before you perform the following steps.
Follow the steps below to sign the android apk using the manufacturer's keys:
- Download the apk from Google Play or from AEM Screens Player Downloads page
- Obtain the platform keys from the manufacturer to get a pk8 and a pem file
- Locate the apksigner tool in android sdk using find ~/Library/Android/sdk/build-tools -name "apksigner"
- <pathto> /apksigner sign --key platform.pk8 --cert platform.x509.pem aemscreensplayer.apk
- Find the path to the zip align tool in android sdk
- <pathto> /zipalign -fv 4 aemscreensplayer.apk aemscreensaligned.apk
- Install aemscreensaligned.apk using adb install to the device
The cross-Android watchdog service is implemented as a cordova plugin using AlarmManager.
The following diagram shows the implementation of watchdog service:
At the time of initialization of the cordova plugin, permissions are checked to see if we have system privileges and thus the Reboot permission. If these two criteria are met, a pending Intent for Reboot is created, otherwise a pending Intent to restart the application (based on its Launch Activity) is created.
2. Keep Alive Timer
A keep alive timer is used to trigger an event every 15 seconds. In that event, you need to cancel the existing pending intent (to reboot or restart the app) and register a new pending intent for the same 60 seconds in the future (essentially postponing reboot).
In Android, the AlarmManager is used to register the pendingIntents that can execute even if the app has crashed and its alarm delivery is inexact from API 19 (Kitkat). Keep some spacing between the timer's interval and the AlarmManager's pendingIntent's alarm.