A watchdog is a timer that must be reset periodically to indicate that the system is working properly. If it is not reset due to a hardware fault or program error, it will generate a reboot signal to restart the device and bring the system to a known operation mode.

The ConnectCore 6 provides a hardware watchdog interface used to restart the module when there is a system or application malfunction.

Digi extends the Android APIs with a System Watchdog Service that is not available in the common Android distributions and provides an API to manage the system watchdog. In addition to this, Digi includes a new software watchdog interface called Application Watchdog Service that is used to restart applications when malfunction is reported instead of restarting the entire system. The system watchdog is common to all applications running in the device, as it relies in the hardware layer, while the application watchdog is specific for each application.

In the Digi APIx javadoc you can find a complete list of the available methods in this API.

Unless noted, all Watchdog API methods (system or application watchdogs) require the com.digi.android.permission.WATCHDOG permission.

If your application does not have the com.digi.android.permission.WATCHDOG permission it will not have access to any Watchdog service feature.

The Watchdog Service includes:

System watchdog

The system watchdog service allows applications to initialize and refresh the system watchdog. If the system watchdog is not refreshed within the configured timeout, the system will reboot.

First of all, a new SystemWatchdogManager object must be instantiated by passing the Android Application Context.

Instantiating the SystemWatchdogManager
import android.app.Activity;
import android.os.Bundle;

import com.digi.android.watchdog.SystemWatchdogManager;

public class SystemWatchdogSampleActivity extends Activity {

    SystemWatchdogManager systemWatchdogManager;

    [...]

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Instantiate the system watchdog manager object.
        systemWatchdogManager = new SystemWatchdogManager(this);

        [...]
    }

    [...]
}

Initialize the system watchdog

Once the system watchdog manager is instantiated, the next step is to initialize the system watchdog. For this operation, a timeout parameter is required. This timeout establishes the maximum time that must elapse without refreshing the system watchdog before restarting the device.

Method Description

init(long)

Initializes the system watchdog service with the given timeout (in milliseconds)

isRunning()

Returns whether the system watchdog service has been initialized or not

getTimeout()

Returns the configured system watchdog service timeout

The init(long) method may fail if the provided timeout is lower than 500 milliseconds, throwing an IllegalArgumentException. If the system watchdog has been already initialized before calling this method, a UnsupportedOperationException will be thrown.

The getTimeout() method may fail with a UnsupportedOperationException if the system watchdog service has not been initialized yet.

Initializing the system watchdog
import com.digi.android.watchdog.SystemWatchdogManager;

[...]

SystemWatchdogManager systemWatchdogManager = ...;

// Check if system watchdog is already running. If not, initialize it to 5 seconds.
if (!systemWatchdogManager.isRunning())
    systemWatchdogManager.init(5000);

// Print configured timeout.
System.out.println("Configured System Watchdog timeout: " + systemWatchdogManager.getTimeout());

[...]
CAUTION! Once initialized, the system watchdog service cannot be stopped and must be refreshed periodically to avoid a system reset. The only way to stop the system watchdog service is to reboot the device.

Refresh the system watchdog

The last step after initializing the system watchdog is to periodically refresh it to avoid a system reset. Use the refresh() method for this purpose:

Refreshing the system watchdog
import com.digi.android.watchdog.SystemWatchdogManager;

[...]

SystemWatchdogManager systemWatchdogManager = ...;

systemWatchdogManager.init(5000);

Thread refreshThread = new Thread() {
    @Override
    public void run() {
        systemWatchdogManager.refresh();
        // Sleep no more time than the configured timeout.
        Thread.sleep(4000);
    }
};
refreshThread.start();

[...]

If the system watchdog was not initialized before calling the refesh() method, an UnsupportedOperationException will be thrown.

Ensure that your application refreshes the system watchdog periodically with a period lower than the configured timeout.

Application watchdog

The application watchdog service allows you to initialize the application watchdog for your application to shut it down in case of failure. It also allows you to execute a pending intent after application is terminated due to failure.

First, a new ApplicationWatchdogManager object must be instantiated by passing the Android Application Context.

Instantiating the ApplicationWatchdogManager
import android.app.Activity;
import android.os.Bundle;

import com.digi.android.watchdog.ApplicationWatchdogManager;

public class ApplicationWatchdogSampleActivity extends Activity {

    ApplicationWatchdogManager applicationWatchdogManager;

    [...]

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Instantiate the application watchdog manager object.
        applicationWatchdogManager = new ApplicationWatchdogManager(this);

        [...]
    }

    [...]
}

Initialize the application watchdog

Once the application watchdog manager is instantiated, the next step is to initialize application watchdog for your application. For this operation, a timeout parameter is required and optionally a PendingIntent. The timeout establishes the maximum time that must elapse without refreshing the application watchdog before shutting down the application. The pending intent allows you to execute an action after application is shut down due to failure, for example an application restart intent.

Method Description

init(long, PendingIntent)

Initializes the application watchdog service for the calling application with the given timeout (in milliseconds) and an optional pending intent (can be null)

isRunning()

Returns whether the application watchdog service has been initialized for the calling application or not

getTimeout()

Returns the configured application watchdog service timeout for the calling application

stop()

Stops the application watchdog service for the calling application

The init(long, PendingIntent) method may fail if the provided timeout is invalid, throwing an IllegalArgumentException. If the application watchdog service has been already initialized for the calling applicationg before invoking this method, a UnsupportedOperationException will be thrown.

The getTimeout() and stop() methods may fail with a UnsupportedOperationException if the application watchdog service has not been initialized yet for the calling application.

Initializing the application watchdog
import com.digi.android.watchdog.ApplicationWatchdogManager;

[...]

ApplicationWatchdogManager applicationWatchdogManager = ...;

// Generate an intent to start this activity again as a new task after failure.
Intent intent = new Intent(this, MyActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Build pending intent.
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);

[...]

// Check if application watchdog is already running. If not, initialize it to 5 seconds.
if (!applicationWatchdogManager.isRunning())
    applicationWatchdogManager.init(5000, pendingIntent);

// Print configured timeout.
System.out.println("Configured Application Watchdog timeout: " + applicationWatchdogManager.getTimeout());

[...]

// Stop the application watchdog service.
if (applicationWatchdogManager.isRunning())
    applicationWatchdogManager.stop();

[...]
Unlike the system watchdog, the application watchdog can be stopped at any time by invoking the stop() method. The reason is that the application watchdog is software controlled while the system watchdog is controlled by hardware.

Refresh the application watchdog

The last step after initializing the application watchdog is to periodically refresh it to avoid the application to shut down. The refresh() method is used for this purpose:

Refreshing the application watchdog
import com.digi.android.watchdog.ApplicationWatchdogManager;

[...]

ApplicationWatchdogManager applicationWatchdogManager = ...;

applicationWatchdogManager.init(5000, null);
Thread refreshThread = new Thread() {
    @Override
    public void run() {
        applicationWatchdogManager.refresh();
        // Sleep no more time than the configured timeout.
        Thread.sleep(4000);
    }
};
refreshThread.start();

[...]

If the application watchdog was not initialized before calling the refresh() method, an UnsupportedOperationException will be thrown.

Ensure that your application refreshes the application watchdog periodically with a period lower than the configured timeout.

Watchdog example

Example: Watchdog

The Watchdog Sample Application demonstrates the usage of the Watchdog API. The sample allows you to interact with the watchdog service by registering the application either to the system or the application watchdog services and report application failure at any time.

You can import the example using Digi’s Android Studio plugin. For more information, see Import a Digi sample application. To look at the application source code, go to the GitHub repository.