BOINC for Android
This doc describes a port of the BOINC client to Android devices. Using this client, BOINC projects can distribute scientific tasks to Android devices, enabling volunteers to contribute CPU time of modern smartphones and tablet computers.
Architecture
The client consists of the regular BOINC core client and an Android-specific GUI. These two components are bundled together, to be distributed in a single APK. Client and GUI communicate via RPCs, similar to BOINC on Windows or Linux.
Aspects of the Android platform
-
Storage: Applications are only allowed to write into two areas of a device's storage space. One is the app's directory, located at /data/data/package.name/, files in this directory can be set executable and run using the Java's Runtime.exec command. This space is "private", so only accessible by the application it belongs to. The second storage location is the device SD card (if present), this is generally accessible by all applications, but mounted non-executable.
-
Permissions: Android restricts access to certain features with its permission system. Required permissions have to be declared in the AndroidManifest file at compile-time, the user then gets prompted to grant access upon installation. BOINC requires the "Network" and permission in order to transmit workunits and setup socket for the RPC communication in-between Manager and Client. The permission "RECEIVE_BOOT_COMPLETED" is used to start the BOINC core client upon boot. Permissions get granted to the App-specific Linux User ID, and therefore also applies to its child-processes.
-
Lifecycle: Activities which are not visible at the moment can get killed by the system. If the user navigates back to a destroyed application, it gets reactivated. In most cases according lifecycle-methods are called, however those are not reliable. This behavior only applies to applications which are executed in Android's Dalvik virtual machine and not to native child-processes like the BOINC Client. As a consequence, the Manager tries to connect to a possibly existing BOINC Client. Only if this attempt fails, a new instance of the BOINC client is executed.
-
Distribution: Like every other application, BOINC comes in an APK package. The BOINC core client gets distributed as part of the Android app and resides in its "assets" directory. When executed, the core client gets copied to the local storage space and executed from there.
Considerations for mobile devices
In order to accommodate the limitations of mobile devices, several features were added to the BOINC Client:
-
Wifi detection: BOINC, by default, does network communication only when logged into a Wifi network. This helps volunteers keeping control of limitations on a data plan.
-
Charging only: BOINC, by default, computes tasks only when the device is being connected to a power source, preventing battery drowns.
-
Battery temperature: Computation is stopped if battery temperature is above 45 C.
-
Battery charge: Computation is stopped if battery charge is below 95%.
Implementation notes
Config file
A config file (currently prefs.xml, should be renamed) will contain boolean flags
- "run at boot?"
- "seen welcome?" (has the user seen the welcome dialog?)
Installation
Unlike Win/Mac, can't do any logic in the installer.
At end of installation, user is asked whether they want to run app. If so, the GUI does the following:
show "Welcome" dialog; say:
- BOINC will run all the time
- only will compute when plugged in and battery mostly charged
- Can changes these using Preferences tab
create prefs.xml
run at boot = true
seen welcome = true
start client
If the user doesn't run the app, nothing will happen until the next time they boot the device (see below).
Boot time
"boot receiver" function
if not "seen welcome" (e.g. prefs.xml doesn't exist)
send notification:
"click to configure BOINC"
if "run at boot" set
start the client (not GUI)
GUI startup
if newer version of client (based on MD5)
if client process running
kill it
copy executable
start client
else
if client process not running
start client
App shutdown by OS
- GUI
- if lose connection to client, wait until system is not low on memory
- then restart client
- client
- don't launch any app if low memory
- Is there a C++ func to find if low mem?
- wrapper
- if task got SIGKILL, temporary_exit(60)
GUI exit
- leave the client running
- need an "exit all" button some