APL Commands (APL 1.1 to 1.3)
(This is not the most recent version of APL. Use the Other Versions option to see the documentation for the most recent version of APL)
Commands are messages that change the visual or audio presentation of the content on the screen. They may be received from Alexa, normally in response to a spoken utterance, or may be generated by event handlers in the APL document, such as in response to a button press. Commands are used to navigate the content, switch between scenes in the Document, and synchronize speech with visual presentation.
For specific commands, see APL Standard Commands.
Commands and screen actions
Commands support the following types of actions on the scene:
- Navigate within a scene
- Scrolling a ScrollView or Sequence
- Scrolling to bring a component into view
- Change the page displayed in a Pager
- Change a component within an existing scene
- Update an input control to reflect a new state
- Change the visibility on an existing component.
- Play/pause a video clip within the existing scene
- Speech
- Read the audio content of a single component
- Read the audio content from more than one components
Command evaluation
The individual properties of a command support data-binding. The command is evaluated by using a combination of the source data-binding context augmented with the event
property that contains information about what caused the command to be issued and the target properties of the recipient of the command.
Event context
Commands evaluate in their source data-binding context. A command received from Alexa evaluates in the top-level data-binding context. That is, a data-binding context that has a viewport and environment defined, and it has access to named resources. A command issued in response to an APL event (such as a screen touch) evaluates in a local data-binding context where the command is defined. For example, consider this TouchWrapper sample.
{
"type": "TouchWrapper",
"bind": [
"name": "myRandomData",
"value": 24.3
],
"onPress": {
"type": "SendEvent",
"arguments": [ "The value is ${myRandomData}" ]
}
}
Pressing the TouchWrapper sets the first argument to "The value is 24.3".
Event definition
The source data-binding context is extended with event data when a command is evaluated. All of the event data is available under the event
property. The event
property contains the source
sub-property, which is system-provided information about the component that caused the event.
"event": {
"source": {
"type": COMPONENT_TYPE,
"handler": EVENT_HANDLER,
"id": SOURCE_COMPONENT_ID, // If assigned
"uid": RUNTIME_GENERATED_UNIQUE_ID,
"value": SOURCE_COMPONENT_VALUE
},
"target": {
PROP1: VALUE1,
PROP2: VALUE2,
...
}
}
Source
The source
section of the payload is meta-information about what caused the event to be generated. The source section is generated by the APL runtime, not the skill author. This information may be used by
the skill developer, but is also intended to be used by analytics. The source
object contains the following values:
Property | Type | Required | Description |
---|---|---|---|
type | String | Yes | The type of the component that initiated this message. |
handler | String | Yes | The name of the event handler that initiated this message. For example, "Press", "Checked". Event handlers are normally named "onXXXX". By convention, the handler is reported as "XXXX". |
id | String | Yes | The id of the component that initiated this message. |
uid | String | Yes | The runtime generated component id |
value | Any | Yes | The value of the component that initiated this message. |
The following table lists the standard source values:
Component type | Value |
---|---|
TouchWrapper | Checked state |
Pager | Current page index |
ScrollView, Sequence | Percentage of scroll view height from top |
Refer to the individual component definitions for the specific source value that will be exposed.
See also: APL standard commands.
Target
The target
property provides state information about the component receiving the event. The values in the target
property are defined on a component by component basis.
Some standard target values are listed below, but the target values vary by component.
Property | Type | Description | Reported By |
---|---|---|---|
color | Color | Current color | Text |
currentTime | Integer | Current playback position | Video |
disabled | Boolean | Disabled state | Component |
height | Number | Height (dp) | Component |
id | String | Component Id | Component |
opacity | Number | Opacity | Component |
page | Integer | Current displayed page | Pager |
paused | Boolean | True if the video is paused | Video |
position | Number | Percentage of scrolled distance | Sequence, ScrollView |
source | String | Image source URL | Image, VectorGraphic, Video |
text | String | Displayed text | Text |
trackIndex | Integer | Index of the current track | Video |
uid | String | Runtime-generated component Id | Component |
width | Number | Width (dp) | Component |
Expression evaluation
-
Some commands take the
componentId
value as atarget
. However, if the component issues the command, and the command targets the same component, thecomponentId
value may be omitted. If you use theExecuteCommands
directive, thencomponentId
must be specified. -
Command data-binding expressions are evaluated when the command runs, not when the command is defined. For example, an
ExecuteCommands
directive may contain data-bound expressions that refer to the global data-binding context. These expressions are evaluated when the command runs on the device, not when the command is constructed in the cloud. -
Both event handlers and the
ExecuteCommands
directive take an array of commands to run. The array is treated the same as a Sequential command with arepeatCount
of 0.
Command Sequencing
The APL runtime environment is responsible for running commands. The runtime contains a single command sequencer which is responsible for running commands.
Sequencer Rules
The sequencer rules are:
- Touching on the screen immediately stops any existing sequence. Any commands in the middle of running are stopped. All commands are flushed.
- A received
ExecuteCommands
directive from the cloud stops any currently running sequence and replaces it with the new commands. - If a command fails to run due to being poorly formed or referring to a non-existent component, the command is skipped. Any delay value associated with that command is still processed.
- All event handlers (e.g.,
onPress
) may be associated with one or more commands. If more than one command is assigned to an event handler the set of commands is implicitly wrapped insideSequential
command.
For example, in the following example the onPress
event handler has an
array of commands. This array is treated as a sequential array to run; here the text component will be spoken and the SendEvent
will
be dispatched after the speech finishes:
{
"type": "TouchWrapper",
"items": {
"type": "Text",
"id": "myText",
"speech": VALUE
},
"onPress": [
{
"type": "SpeakItem",
"componentId": "myText"
},
{
"type": "SendEvent",
"arguments": [ "The button was pushed and spoken have I" ]
}
],
}
APL supports a single running command sequence at one time. When a new command sequence starts, the old command sequence stops abruptly and any commands in the old command sequence that haven't started don't run. A Source of a command or set of commands is something that triggers running commands. A source can be a user interaction or based on some passage of timing triggering an action. The following types of sources exist:
- An Alexa
ExecuteCommands
directive. - Touching on the screen
- Dragging on the screen (scrolling)
- Certain
Video
component events (e.g.,onTrackUpdate
) that occur in a background video.
The source fires a series of one or more commands to run, which in turn may consist of additional sets of commands to run in series or in parallel. Each of the commands may occur instantaneously or may take a period of time.
Command Trees
A command tree is the complete set of commands that runs. Command trees come about because commands may be nested or because a command may cause a new event handler to fire. Various primitive commands have nested commands:
Parallel
Sequential
OpenURL
User-defined commands also contain nesting. Primitive commands may also trigger event handlers; for
example, the onScroll
event may be triggered by Scroll, ScrollToComponent, or event
SpeakList.
Command trees can run to completion or they can stop before completion. A stopped command tree stops running all commands immediately. In short, a source starts the command tree. The command tree might run to completion or may be preemptively stopped.
A sample command tree might look as follows:
ExecuteCommand
+ Scroll (distance=-10000) // Scroll to top
+ onScroll // Fires multiple times as the view scrolls to the top
+ SetValue (name="opacity", value=event.source.value * 10) // Change opacity
+ SpeakItem (id) // Scroll item into view and run karaoke
+ onScroll // Fires multiple times as the view scrolls
+ SetValue (name="opacity"....)
+ PlayVideo (synchronously)
+ onStart // Fires once
+ onTrackUpdate // Fires each time a new track is displayed
+ SetValue (name="progress"...) // Update a progress bar display
+ onStop // Fires once
In the above example, an Alexa ExecuteCommands
message scrolls to the
top of the screen, speaks one of the items, and plays a video
(presumable in a separate section of the screen). If the user touches on
the screen during playback, any running speech, scrolling, or video
playback will be halted.
Rules:
- You get a single "live" user-initiated source. If there is an existing, running user-initiated source, that ends and the new user-initiated source starts.
- Non-user-initiated sources always run to completion. The only exception is that they stop when the APL template is closed. Any number of non-user-initiated sources may be active at the same time.
Fast mode
The commands that run as a part of a command tree may include commands that take a visible amount of time to run. For example, scrolling a list on the screen, speaking text, or simply delaying an effect. The running command sequence may trigger event handlers that start new command sequences running. In the case of the onScroll event handler, this may fire at the display frame rate during a long scroll operation. If the onScroll event handler was allowed to trigger a command sequence that took time to run (such as speaking text), the system would have to either queue up the spoken text for later processing or it would have to repeatedly interrupt the spoken text with new spoken text.
To avoid having a repeated interruptions of spoken text, APL introduces
the concept of normal- and fast mode for running commands. Any command
sequence spawned from an event handler that might run at frame rate runs in fast mode. All other command sequences run in
normal mode. Fast mode ignores all delay
settings in
commands and ignores commands that take measurable time to run. The
event handlers have the following behavior:
Event Handler | Behavior |
---|---|
Component onMount property |
Normal mode |
Document onMount property |
Normal mode |
Pager onPageChanged property |
Normal or fast mode |
ScrollView onScroll property |
Fast mode |
Sequence onScroll property |
Fast mode |
TouchWrapper onPress property |
Normal mode |
Video onEnd property |
Normal or fast mode |
Video onPause |
Normal or fast mode |
Video onPlay |
Normal or fast mode |
Video onTimeUpdate |
Fast mode |
Video onTrackUpdate | Normal or fast mode |
Events that occur due to user interaction (such as pressing a touch wrapper) always run in normal mode. Events such as scrolling or time updates always occur in fast mode. Events that can run in either mode can be triggered by a normal action (such as a video track ending) or by a command that was ultimately triggered by fast mode (such as a video pause from a scroll event). External commands run in normal mode.
Each command documents its behavior in fast mode. The following table summarizes fast-mode behavior:
Command | Fast mode behavior |
---|---|
AnimateItem |
Jumps to end state. |
AutoPage |
Ignored |
ControlMedia |
Ignored for command=play , run otherwise |
Idle |
Ignored |
OpenURL |
Ignored |
Parallel |
Runs |
PlayMedia |
Ignored |
Scroll |
Ignored |
ScrollToComponent |
Ignored |
ScrollToIndex |
Ignored |
SendEvent |
Ignored |
Sequential |
Runs |
SetPage |
Ignored |
SetValue |
Runs |
SpeakItem |
Ignored |
SpeakList |
Ignored |
Command tree ending
When a command tree stops, APL makes a number of assumptions to get the device to a consistent state:
- Scrolling stops
- Page turns are canceled and return to either the original page or the next page (whichever is closer)
- Speaking immediately stops
- Scene changes and structural changes to the layout "jump" to their final position.
"Normal" mode is how commands normally run. "Fast" mode eliminates all duration for commands. The delay property of the command is ignored. All commands that take time to run (such as scrolling) are either ignored in fast mode. Individual commands document their behavior in "fast" mode.
Sequencer summary
When a new series of commands are received for processing (either
supplied externally or internally due to an action like pressing a
buttom), any existing command tree stops. The new
series of commands are processed in order with fast mode set to false
.
For each command, do the following:
- Evaluate the
when
clause. If it evaluates tofalse
, skip the command and move on the next command in the array. - Evaluate the
delay
property. If it is greater than zero, pause that duration in milliseconds. - Evaluate the type of the command. There are three possibilities:
- The command could be a standard command such as
SendEvent
. Check to see if all required command properties have been set. If a required property is missing, ignore the command and continue. If all required properties are set, run the command and wait until it finishes. - The command could be a user-defined command. Run the command following the rules defined in that section.
- The command could have an unrecognized type. Ignore the command and continue.
- The command could be a standard command such as
Note that standard commands may trigger event handlers. Those event handlers are generally runs in fast mode.
Last updated: Nov 28, 2023