Skip to content
Andrei F edited this page Aug 7, 2016 · 18 revisions

Installation / compatibility ˄

Download on the Play Store

Discussions maybe be held or questions asked here:

Initialization ˄

  • Synapse expects a su program in the environment PATH to execute.
  • Synapse expects a uci program in the environment PATH to execute.

uci is expected to serve two possible parameters in its first parameter position;

  • uci config which will return via standard output a JSON formatted configuration output representing the element domain model.
  • uci actionpath which will return via standard output a plaintext absolute path to the folder containing the helper executables.

The uci back-end serves as the configuration to the application, declaring the interface elements and actions available to it. The location of the executable doesn't matter to the app as long as it has access to it via PATH.

The actionpath serves as a second-order executable environment that is internally used on top of PATH (it is just exported to PATH in the internal command shells). Its purpose is to facilitate separation of helper executables from other system executables. The actionpath is given the highest execution priority, above /sbin.

The common implementation is to include it into the ramdisk of a kernel: this method allows binding of the controls to a specific kernel image. Optionally, it can be injected anywhere else such as the system partition and symlinked to /xbin or /bin. The latter requires that the domain model (uci config) be perpetually dynamic to avoid conflicts caused by differing kernel or OS versions.

Actions ˄

An action is any executable found in the location provided by uci actionpath or in the common executable environments provided by PATH.

An action is expected to be in itself a unique identifier inside the domain model of the application.

Parameters may be concatenated to the action's executable name; the resulting string is an element's action.

Example: generic /sys/block/mmcblk0/queue/read_ahead_kb defines an action to the generic executable and always passes /sys/block/mmcblk0/queue/read_ahead_kb as its first parameter.

Action executables are expected to have two modes of functioning:

  • Read-mode; The action is executed without any additional parameters, and is expected to return via standard output an action-value.
  • Write-mode; The action is executed with an additional parameter representing an action-value, and is expected to return via standard output an action-value.

An action-value is an arbitrary value of undefined type and length, terminated by a \n newline character.

The application remembers and saves action-values on a key-value basis, where the key is the unique identifier provided by the action itself. They are stored internally in a database in the system's application data under com.af.synapse/databases/actionValueStore.

Example: generic

if [ -f $1 ];then
	if [[ ! -z $2 ]]; then
		echo $2 > $1
	fi

	echo `cat $1`
fi

The above action executable takes a file path and returns its contents. If an action-value is passed on, the action-value is forwarded to the standard input of the given file path.

In the case of generic /sys/block/mmcblk0/queue/read_ahead_kb, it will read out the file and output it via standard output, or pipe the given parameter into the file's standard input and then read out the file to standard output.

The point of actions are that they be used as configurable and dynamic translation layers which provide large amount of flexibility.

Advanced example: colour

if [[ ! -z $2 ]]; then
	let "RC=($((16$2)) & 16711680) >> 16";
	let "GC=($((16$2)) & 65280) >> 8";
	let "BC=$((16$2)) & 255";
fi

case $1 in

scr_red)	;&
scr_green)	;&
scr_blue)	;&
scr_yellow)	;&
scr_cyan)	;&
scr_magenta)	;&
scr_white)	;&
scr_black)
	P=/sys/class/misc/mdnie/hook_control/

	if [[ ! -z $2 ]]; then
		echo $RC > $P/$1_red
		echo $GC > $P/$1_green
		echo $BC > $P/$1_blue
	fi

	echo $(printf "#%02X%02X%02X\n" $(cat $P/$1_red) $(cat $P/$1_green) $(cat $P/$1_blue))
	;;
esac

The above translates a hexadecimal representation of a colour to, and from three sysfs nodes representing each component in decimal.

JSON domain model ˄

uci config, as mentioned, is expected to output a JSON formatted domain model of the interface elements.

Root grammar

The root structure is:

{
    "sections": [
     ....
    ]
}

The root object contains a sections name/value pair whose value is an array of objects representing sections.

A section is defined as:

{
    "name":"Section name example",
    "elements":[
      ....
    ]
} 

Section names can also be localised:

{
    "name":{ "en":"Section name example", "fr":"Nom de section exemplaire" },
    "elements":[
      ....
    ]
} 

A section contains a name key with the name of the section as its value, and an elements key with an array of objects as its values.

NOTE: The parser accepts non-strictly formatted JSON as input, such that structures as the following are still correctly interpreted:

{
    name:MySection,
    elements: [
      ....
    ]
}

Each element represents a View inside the LinearLayout of a section.

Localisation ˄

Localisation is supported on the element level. Any string-based interface elements can be localised.

Localisable grammar

Where a non-localised element string would look as follows:

description:"This is your desired default description language-independent"

A localised one would look as follows:

description:{
    en:"This is your desired English language localisation and also fall-back localisation.",
    fr:"This is your French language localisation",
    es:"This is your Spanish language localisation"
}

If your device is currently set to a country-specific locale such as es_ES for the Spain locale, if a es_ES locale is not specifically defined, the application will try to fall back to a general language locale. In the above case es_ES and es_US or any other regional locale of Spanish will fall back to es. Localisation codes are standard Java defines, as listed here, but also highly depend on the ROM.

For a listing of available elements and their JSON notations please read: ###Element listing and documentation ˄

A fully valid domain model can be now built given the previous described elements:

{
   sections:[
      {
         name:CPU,
         elements:[
            {
               STitleBar:{
                  title:"CPUFreq scaling"
               }
            },
            {
               SSeekBar:{
                  title:"CPU max frequency",
                  description:"Set the maximum freqency the CPU scales up to.",
                  unit:"MHz",
                  step:100000,
                  weight:0.001,
                  min:100000,
                  max:2000000,
                  default:1600000,
                  action:"generic /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
               }
            },
         ]
      },
      {
         name:GPU,
         elements:[
            {
               SPane:{
                  title:"GPU scaling settings",
                  description:"By editing the following configurables you can change the performance behaviour of the GPU."
               }
            },
            {
               SOptionList:{
                  title:"GPU max freq",
                  description:"Set the maximum freqency the GPU scales up to.",
                  default:480,
                  unit:"MHz",
                  action:"generic /sys/devices/platform/pvrsrvkm.0/sgx_dvfs_max_lock",
                  values:[
                     700,
                     640,
                     600,
                     532,
                     480,
                     350,
                     266,
                     177,
                  ]
               }
            },
         ]
      }
   ]
}

The domain models can be extended in breadth with no limit. Here is an example of a 7-section model with over 150 elements.