Developer Console

DIAL Integration (Fire TV)

Amazon Fire TV devices support the DIAL (Discovery-and-Launch) protocol through the Whisperplay service.

About DIAL

DIAL (Discovery-and-Launch) protocol is an open protocol that enables your Fire TV app to be discoverable and launchable from another device via a second-screen app. Both Fire TV and the second-screen device must be on the same network.

DIAL is not a bit-streaming or screen mirroring API, it enables apps on a second-screen device to find and launch apps on a Fire TV (with an optional payload). In most cases, you own and implement both the second-screen app (to send a launch message), and the corresponding Fire TV app, aka first-screen app (to receive that message).

For more information about the open DIAL protocol and to register your app with the DIAL service, see the DIAL website.

Implementing DIAL

In the simplest case (launch-only), DIAL functionality does not require any changes to your Amazon Fire TV app's code, but you do need to modify your app's manifest and resources to indicate support for DIAL and to accept launch intents. An example of this core, launch-only interaction is illustrated in the following diagram:

DIAL launchonly interaction

In most cases, though, you will also want to modify your first-screen (Fire TV) app’s code to process DIAL launch parameters (e.g. deep-links) and to provide feedback to the DIAL server's additionalDataUrl.

In general, the following five steps should be followed to leverage most DIAL features and provide the best customer experience:

  1. Register your Fire TV app with the DIAL registry. See About the Registry for details.
  2. In your Fire TV app, modify the Android manifest to support DIAL. See Step A: Modify your Android Manifest.
  3. In your first-screen Fire TV app, add a whisperplay.xml file to your app's resources. See Step B: Add the whisperplay.xml File.
  4. In your first-screen Fire TV app’s code, handle launch intents and extras. This step is only necessary if your second-screen app sends a payload in the DIAL launch request and/or will expect additional data from the Fire TV app, through the DIAL Server. See Step C: Handle Launch Intents and additionalDataUrl.
  5. In your second-screen app, implement the DIAL protocol to discover and launch apps on Fire TV. See the DIAL website for more information, and specifically the information in Details for Developers. A short description of changes to the second-screen app is provided below.

Changes to Your Fire TV (First Screen) App

The following sections list changes you must make to your Fire TV app.

Step A: Modify your Android Manifest

There are two changes you must make to your Android manifest (AndroidManifest.xml) to support DIAL:

  • Add a <meta-data> element to <application> that indicates support for DIAL.
  • Add the DEFAULT category to your launch intent.

In the <application> portion of your manifest, add the following <meta-data> element:

<application ... >
    <meta-data android:name="whisperplay"  android:resource="@xml/whisperplay"/>
    ...
</application>

Next, add the DEFAULT intent category (XML below) to your primary (main) activity's <intent-filter> element. As described in the next section, you may also define your own custom launch action for DIAL to invoke.

    <activity android:name=".MainActivity"
              android:label="@string/title_activity_main" >
        ...
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

Step B: Add the whisperplay.xml File

Add a file called whisperplay.xml to your app's resources, in your app's res/xml/ directory.

<?xml version="1.0" encoding="utf-8"?>
<whisperplay>
  <dial>
    <application>
    
      <!-- The name of your DIAL app as registered in the DIAL registry -->
      <dialid>YourDialAppName</dialid>
      
      <!-- The collection of authorized client origins -->
      <authorizedOrigins>
        <origin>https://www.example.com</origin>
        <origin>https://*.test.com</origin>
        <origin>package:com.example.dialapp</origin>
      </authorizedOrigins>
                 
      <!-- Optional Intent action to use when starting your app's Activity -->
      <!-- By default, will attempt to resolve your main Launcher Activity -->
      <startAction>android.intent.action.MAIN</startAction>
      
      <!-- Optional Intent action to use when DELETE command is sent from the
           second-screen app (sent before stopping your activity) -->
      <!-- By default, no extra intent is sent on DELETE -->
      <stopAction>YourDeleteAction</stopAction>
    
    </application>
  </dial>
</whisperplay>

CORS support via <authorizedOrigins>

Please be sure to review the DIAL spec v2.2.1, section 6.6 for more details on the additional requirements for CORS authorization and client origins. The Amazon implementation requires your app to specify a collection of authorized CORS origins within your first-screen app’s whisperplay.xml file (see example above). The format allows for wildcard matches using the "*" character which will match zero-to-many characters. Note that certain insecure URI schemes (including file: http:, ftp: and others) are explicitly forbidden regardless of whether they appear in your authorized list.

Take care when specifying your authorized origins to not be overly permissive. For example, if you want to authorize both https://test.amazon.com and https://amazon.com DO NOT specify your authorized origin as *amazon.com. This is overly permissive and may inadvertently authorize an unexpected origin such as https://evilamazon.com. Instead, you could define the collection as shown below which ensures all origins are based on the domain you own:

<authorizedOrigins>
  <origin>https://*.amazon.com</origin>
  <origin>https://amazon.com</origin>
</authorizedOrigins>

Step C: Handle Launch Intents and additionalDataUrl

If your app accepts a DIAL payload (information that can be passed to your app via the DIAL launch request), that payload will be delivered as a String Intent extra with the key com.amazon.extra.DIAL_PARAM. The additionalDataUrl used by your first-screen app to optionally POST additional information is delivered as another String Intent extra with the key com.amazon.extra.DIAL_ADDITIONAL_DATA_URL. It is safe to assume that the additionalDataUrl will be in the form http://127.0.0.1:8009/apps/<YourDialAppName>/dial_data to which your first-screen app may POST data.

(Optional) POST Additional Data

If you would like to enable very rudimentary two-way communication or a simple feedback mechanism from your first-screen app back to your second-screen app, you may opt to use DIAL’s additionalDataUrl field. A common use case for this would be to share a session token or some other information tied to your first-screen application’s state. You can think of this as an XML document that your first-screen application makes available to your second-screen app that persists as long as the Fire TV is not rebooted. In order for the Fire TV app to successfully POST to the additionalDataUrl, the corresponding origin must be registered in the <authorizedOrigins> collection in whisperplay.xml.

Refer to the DIAL docs v2.2.1, section 6.3 on the specific formats expected and provided by the additional data mechanism for both first- and second-screen apps.

Changes to the Second-screen App

The following sections list changes you need to make to the second-screen app.

Step A: Implement the DIAL-enabled device discovery service

On the second-screen app (aka the DIAL client), implement the client specification of the DIAL protocol. DIAL discovery is built on top of the UPnP/SSDP specification. In a background activity or thread, send a UDP M-SEARCH request with the search target as "urn:dial-multiscreen-org:service:dial:1".

Fire TV responds to the M-SEARCH request with a response containing a unique service name (USN), the location/URL to obtain a device description, and the search target. Additionally, there may be an extra WAKEUP header included indicating the TV currently has the capability to be woken from suspend mode using magic packets (refer to the DIAL 2.2.1 spec, section 7 for more details). Since it is possible to receive multiple M-SEARCH responses from the device, you must extract unique devices based on the USN.

The following is a sample request and response.

Sample M-SEARCH Request:

M-SEARCH * HTTP/1.1
HOST: 239.255.255.250:1900
MAN: "ssdp:discover"
MX: 10
ST: urn:dial-multiscreen-org:service:dial:1
USER-AGENT: OS/version product/version

Sample M-SEARCH Response:

HTTP/1.1 200 OK
    USN: uuid:7b077d4c-a222-5b72-0000-0000182185c7::urn:dial-multiscreen-org:service:dial:1
    CACHE-CONTROL: max-age=1800
    EXT:
    ST: urn:dial-multiscreen-org:service:dial:1
    LOCATION: http://192.168.1.141:60000/upnp/dev/7b077d4c-a222-5b72-0000-0000182185c7/desc
    SERVER: Linux/4.4.120 UPnP/1.0 Cling/2.0

Next, to obtain more information about the device, send an HTTP request using the device description location URL in the M-SEARCH response. The response contains an important attribute in its header called Application-URL, referred to as the DIAL REST Service. This Application-URL is subsequently used to interact with the app on the device. From the response body, it is useful to extract and store the device-friendly name, model name, and manufacturer to display these values to the user.

After the processing of the M-SEARCH and device descriptions requests is complete, the list of devices found can be presented to the user in the UI.

Step B: Get App Status

Before launching the app on the device, it is useful to detect the state of the app on the device (and optionally read additionalData to load cached information from your first-screen app). To get the state of the app, once the user selects a device to launch the app on, send an HTTP GET request to the DIAL REST service with the app name as the resource name. The app name in the request must match the name registered in the DIAL registry (and specified in your whisperplay.xml file).

If the app name is not recognized and/or the app is not installed, an HTTP 404 error is returned. The user could be presented the option on the second-screen device to install the app on the first-screen device from the Appstore, but this functionality is out of scope for the DIAL protocol.

If the HTTP request is successful, the DIAL server responds with an HTTP 200 OK response. The response body contains an attribute that informs the state of the app — hidden, stopped, running, or is installable (note that installable and hidden are not currently supported by the Fire TV DIAL server), and any XML-formatted additionalData that was previously POSTed to the additionalDataUrl by the first-screen app.

Step C: Launch the App

Next, launching the first-screen app is as simple as sending an HTTP POST request to the DIAL REST Service with the app name as the resource name, and optional payload in the request body to send to the app as a launch parameter. A common use case could be a link to video or music content to play within the app. The DIAL server launches the app with the specified launch intent and includes the optional payload sent by the mobile app in the com.amazon.extra.DIAL_PARAM intent extra. If the second-screen app expects additional data from the first-screen app, the additionalDataUrl from the request parameter as specified in DIAL protocol is sent in the com.amazon.extra.DIAL_ADDITIONAL_DATA_URL intent to the first-screen app (see Step C: Handle Launch Intents and additionalDataUrl).

The first-screen app is responsible for handling actions in response to the payload sent from the second-screen app. Subsequent GET requests issued by any second-screen app can be used to read any additional data that was POSTed by the first-screen Fire TV app (e.g. a viewing session token to synchronize multiple clients).

As with any app development, care must be taken to clean up and close network connection resources, handle exceptions, launch threads in non-UI blocking threads, and fail gracefully when network operations fail.

Version History

  • April 5, 2021: The version of DIAL Server on Fire TV devices supports v2.2.1. This includes enhancements to the CORS authorization model and the new <authorizedOrigins> tag. Currently, the Fire TV DIAL service does not support remote app installation or the hidden app state.
  • Aug 1, 2020: The version of DIAL Server on Fire TV devices supports v2.1. The additionalDataUrl in a launch request is supported on all Fire TV devices and WoW/WoLAN feature is supported on Fire TV Editions.

Last updated: Nov 12, 2021