In Android development, creating and running a native daemon can be essential for managing background processes that require low-level access or persistent execution. A native daemon runs in the background, performing tasks independent of user interaction. In this post, we will explore how to create a native daemon in Android and configure it to run from the init.rc
file. This guide will include detailed examples to ensure that even beginners can follow along.
What is a Native Daemon?
A native daemon is a background service written in C or C++ that performs specific tasks continuously or at scheduled intervals. Unlike Android services that are typically written in Java, native daemons are directly executed by the Linux kernel, making them more suitable for low-level system tasks.
Creating a Native Daemon
- Writing the Daemon in C/C++ First, let’s write a simple native daemon in C. This example will create a daemon that logs a message to a file every minute.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
void daemonize() {
pid_t pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
if (pid > 0) {
exit(EXIT_SUCCESS);
}
if (setsid() < 0) {
exit(EXIT_FAILURE);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
int main() {
daemonize();
FILE *log;
while (1) {
log = fopen("/data/local/tmp/daemon.log", "a+");
if (log == NULL) {
exit(EXIT_FAILURE);
}
time_t now = time(NULL);
fprintf(log, "Daemon alive at %s", ctime(&now));
fclose(log);
sleep(60);
}
return 0;
}
Explanation:
- Daemonize Function: This function forks the process, detaches it from the terminal, and closes standard file descriptors, turning it into a daemon.
- Main Loop: The main loop writes a timestamp to a log file every minute.
- Compiling the Daemon Compile the daemon using the Android NDK:
vim Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := exampleservice.c
LOCAL_MODULE := exampleservice
LOCAL_MODULE_TAGS := debug
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
LOCAL_SHARED_LIBRARIES := liblog
include $(BUILD_EXECUTABLE)
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk
Ensure that you set up your Android.mk
file correctly to compile the daemon.
Running the Daemon from init.rc
The init.rc
file is the primary initialization script in Android that runs during system startup. To run your daemon at boot, you’ll need to modify this script.
- Copy the Daemon to the System Place the compiled daemon binary in a system directory, such as
/system/bin
or/vendor/bin
:
adb push daemon /system/bin/
- Editing
init.rc
Open theinit.rc
file and add the following service entry:
service mydaemon /system/bin/daemon
class main
user root
group root
oneshot
Explanation:
- service: Defines a new service named
mydaemon
. - /system/bin/daemon: Specifies the path to your daemon binary.
- class main: Runs the service in the main class, which is started during boot.
- user root: Runs the service as the root user.
- group root: Runs the service under the root group.
- oneshot: Ensures the service only runs once and does not restart automatically.
- Testing the Daemon Reboot your device, and your daemon should start running. You can check the log file at
/data/local/tmp/daemon.log
to confirm that it’s working.
Best Practices
- Security: Ensure that your daemon does not expose any security vulnerabilities. Running as root provides full system access.
- Resource Management: Avoid creating resource-intensive daemons that can drain battery life or cause performance issues.
- Error Handling: Implement robust error handling within your daemon to prevent it from crashing or causing system instability.
Hello!
Thanks for this great post, I wonder where the init.rc file should go and where can I add SELinux policies?