This page provides a more detailed reference on the syntax and capabilities of the Binder shell.
The Binder Shell is a basic implementation of the POSIX shell syntax (spec at http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html) with a few extensions. While it should be able to parse the full POSIX grammar correctly, there are a few features, most notably pipes, that aren't implemented yet.
Besides these limitations, the shell provides the same general environment one expects from a POSIX shell:
variable="something" if [ "$variable" -eq "something" ] echo "Variable is something" else echo "Variable is something else" fi
For the rest of this document we will assume that you are already familiar (as much as you want to be) with POSIX shell syntax.
As these values propagate between the command and the shell, their type is propagated as well. For example, if you have an environment variable SOMETHING
that contains a reference to an IBinder object, you can pass it to a function like a normal environment variable:
inspect $SOMETHING
The second argument that the inspect
command receives will be a SValue containing a pointer to the same binder. The command can similarly return a result SValue containing an object that the shell can use.
$(cmd ...)
to embed the output of a command into the place this construct appears. The Binder Shell adds a variant $[cmd ...]
, which embeds the result of a command. Because command results are now an SValue, this allows you to propagate typed data through the shell.
For example, there is a lookup
command that returns the SValue of a particular property in the context. This can then be assigned to an environment variable:
SURFACE=$[lookup /services/surface]
The environment variable can be passed to another command:
put $SURFACE show_updates true
One could even write commands that take typed data as input and generate a typed result. For example, if we had two theoretical commands, rect and point, which generate SValues containing data of their respective types, we could write shell code like this:
RECT=$[rect 0 0 100 120] POINT=$[point 10 10] NEWRECT=$[rect_offset $RECT $POINT]
Or even:
NEWRECT=$[rect_offset $RECT $[point 10 10]]
This facility is used extensively by the standard commands for working with the Binder runtime, such as new
, new_process
, and invoke
.
@{ ... }
section defines SValue mappings (separated by ->
) and sets (separated by ,
); a combination of both can be used to create multiple mappings. Some examples:
@{ data } # A simple string @{ something, somethingelse } # A set of strings @{ param->value } # A mapping @{ {param->value}[param] } # Lookup in a mapping @{ param1->something, # Multiple mappings param2->somethingelse } @{ param1->{ value1, value2 } } # Mapping to a set @{ param1->{ nested->value } } # Mapping to a mapping @{param1->{nested->value}} # All spaces are optional and ignored
Tokens inside of an SValue context are typed. If the token is all numbers, it is interpreted as an integer; if it is all numbers with a single period, it is a float; true and false are the corresponding boolean values; otherwise, it is a string:
@{ 1 } # An integer @{ [abcd] } # An integer of ASCII characters @{ 1.0 } # A float @{ true } # Boolean truth @{ 1->something } # Integer mapped to string
You can also explicitly specify the type of a token. If a token is enclosed in double quotes, it is always converted to a string. If you prefix it with (), you can force it to one of the fundamental types: (int32), (float), (string), (bool):
@{ "1" } # A string @{ (string)1.0 } # Also a string @{ (int64_t)10 } # A 64 bit integer @{ (nsecs_t)123456 } # A time @{ (float)1 } # A floating point number @{ (int32_t)$VAR } # Cast to an integer @{ (bool)1 } # Boolean truth @{ "true" } # The string "true"
Finally, environment variables and command results can be used as tokens:
$ SURFACE=$[lookup /services/surface] $ M1=@{ 0->$SURFACE } # Integer mapped to an object $ M1=@{ 0->$[lookup /services/surface] } # Equivalent $ M2=@{ a->$M1, b->"foo" } # Make set of mappings $ M=@{ $M1 + $M2 } # Combine the mappings $ V=@{ $M[0] } # Look up a value in a mapping
See Binder Shell Data for more examples.
$ E=$[inspect /services/surface org.openbinder.services.IErrAlert] $ RESULT=$E.ShowAlert("Alert text")
The arguments are supplied as a comma-separated list, and are parsed as a normal command line: plain text will be interpreted as strings, you can use $
for variables, $[]
to run commands, @{}
to build typed values, etc.
foreach
statement for operating on IIterable and IIterator objects, and SValue mappings. The general syntax is:
foreach [key] value [in|over] data [data ... ]; do statements done
If key is not specified, then value will contain {key->value}
mappings for each item. The data items can be variables or other constructs.
The foreach ... in ...
form allows you to operate on iterators the data you supply must be either an IIterable or IIterator object, or a path to an interable object in the namespace, or a mapping containing values that are iterables or paths. For example, to iterate over all items in /services
, you would write this:
foreach key value in /services; do echo $key is $value done
Resulting in:
informant is SValue(sptr<IBinder>(0x80967c4 9Informant)) memory_dealer is SValue(sptr<IBinder>(0x8090f34 13BMemoryDealer)) tokens is SValue(sptr<IBinder>(0x809a13c 2TS))
The foreach ... over ...
form allows you to operate on value mappings it will simply decompose the data into its separate mappings. For example:
foreach k v over @{0->1, 2->3, 1->a} string $[lookup /services/informant]; do echo $k is $v done
Results in:
0 is 1 1 is a 2 is 3 SValue(wild) is string SValue(wild) is SValue(sptr<IBinder>(0x8096f74 9Informant))
This is a good example of why SValue mappings are defined the way they are, where a simple value V
is formally the mapping {wild->V}
. Notice this coming into play for the last two items, which are not normally considered to be mappings.
Also notice a special property of SValue ordering related to integers. The order that SValue holds its sets in is not defined to be anything useful, except in the case of integer keys: these will be in their natural order. This property is convenient in dealing with sets of mappings of integer keys representing arrays.