Google TV

Anymote Protocol

The Anymote Protocol allows applications running on remote devices to send events to Google TV. The protocol is based on a client-server model, with communications based on protocol buffers. Clients search for a server on the local network. When a client wants to connect to a server it has discovered, it does pairing authentication. After a successful pairing, both the client and the server have certificates specific to the client app, and can communicate in the future without the need to authenicate again. The transport layer uses TSL/SSL to protect messages against sniffing.

Terminology:

Remote device
Smart phone or tablet device that hosts the remote application.
Remote application
The application on a remote device that communicates with Google TV.

Contents

Introduction

By using Anymote protocol, remote applications can act as fully-functional Google TV remote control apps, customized controllers for specific Google TV apps or extend functionality of other Google TV apps. For example, you can build a remote app and can switch the Google TV to display a particular web page.

To see an example of an application that uses the Anymote Protocol, try the Google TV Remote Android application that's available from the Google Play Store. This application turns your Android phone into a remote controller for Google TV.

This app is open source, and you can obtain the source files from the google-tv-remote site.

For both Java and C++ implementation of the Anymote protocol see the anymote-protocol project site. For an example of implementing Chrome extensions that use Anymote protocol to communicate with Google TV see the google-tv-chrome-extensions project site.

Using the Anymote Protocol

Google TV provides an Anymote Protocol service that receives and responds to Anymote messages. Remote applications are clients that send Anymote messages to the Anymote service. The Anymote Protocol messages are in protocol buffers format. The protocol uses the following protocol buffer definitions:

  • keycodes.proto
  • remote.proto

The protocol definitions are available from the anymote-protocol project site.

Protocol Buffers

Protocol buffers are a language-neutral, platform-neutral, extensible mechanism for serializing structured data. You can write applications that use protocol buffers in Java, C++, and a number of other programming languages.

For tutorials for using protocol buffers, see https://developers.google.com/protocol-buffers/docs/tutorials.html.

Protocol buffer libraries are available from the protobuf project site.

The Google TV server implementation of the Anymote Protocol uses the MessageLite protocol buffer interface for efficiency. For data serialization/deserialization, it uses the writeDelimitedTo() and mergeDelimitedFrom() methods. (The encoded protocol buffer is preceeded with its size encoded as variable length int - https://developers.google.com/protocol-buffers/docs/encoding.html). We recommend that you use the MessageLite interface in your client applications because it has a smaller footprint, which is an advantage for resource limited systems like Android and other mobile phones.

Remote Messages

Messages between a client application and Google TV are sent as RemoteMessage protocol buffers. The RemoteMessage specifies either a RequestMessage (from the client) or a ResponseMessage (from Google TV).

message RemoteMessage {
   // Optional sequence number. If present in the message with request_message
   // the other end will reply with response_message with the same
   // sequence_number
  optional uint32 sequence_number = 1;
  
  // Message for a request
  optional RequestMessage request_message = 2;
  
  // Message for a response
  optional ResponseMessage response_message = 3; 
} 

When a client application sends a message to Google TV, it must set the RequestMessage. Google TV will send back a RemoteMessage that has the ResponseMessage field set. Unsupported messages (for example, a request sent to the device or a response sent to the server) are ignored.

To keep track of responses to an outgoing request, the client app can provide a value for the optional sequence_number field. The server's response to the request contains the same sequence number value..

Request Messages

Messages going from the client to the server must be encapsulated in a RequestMessage.

message RequestMessage { 
  // Message for a key event   
  optional KeyEvent key_event_message = 1;   

  // Message for a mouse movement   
  optional MouseEvent mouse_event_message = 2;   

  // Message for a mouse wheel event   
  optional MouseWheel mouse_wheel_message = 3;   

  // Message containing data   
  optional Data data_message = 4; 
  
  // Message send upon connection   
  optional Connect connect_message = 5;   

  // Fling message   
  optional Fling fling_message = 6;  
}      

At most one event may be present in the request. If no request subfield is present, the request is considered to be a "ping" message, asking the server to reply with an empty response.

Response Messages

Google TV sends messages back to the device as ResponseMessages:

message ResponseMessage {
  // Data message 
  optional Data data_message = 1; 

  // Data list message -- ignored
  optional DataList data_list_message = 2; 

  // Fling result
  optional FlingResult fling_result_message = 3; 
}

A DataList message is currently ignored. A ResponseMessage with no type is a response to a RequestMessage with no type.

Request Events

Each RequestMessage corresponds to an event sent to Google TV from the remote app. The events are::

Connecting a Device

When a device connects to the server, it can send a message to describe itself.

message Connect { 
  // Remote device name
  required string deviceName = 1;

  // Version number for a given device
  optional int32 version = 2;
}

The server can then reply with a data message containing instructions if needed.

The connection response message:

message ConnectMessage {  
   // Device name
   required string remoteDeviceName = 1;

   // Device version number
   optional int32 remoteVersionNumber = 2;
 } 

Key events

A key event message includes the keycode for the key, and the type of action that occurred (press or release).

// Sends a key event to the server
message KeyEvent {
  // Key code
  required Code keycode = 1;

  // Action (Up/Down)
  required Action action = 2;
}

All the keycodes and the actions are defined in the keycodes.proto file.

Mouse events

Mouse click events are sent as key events prefixed with the string BTN_. For example, BTN_MOUSE, BTN_LEFT, BTN_RIGHT, BTN_MIDDLE.

For a mouse click-down event:

anymoteSender.sendKey (Code.BTN_MOUSE, Action.DOWN);

For a mouse click-up event:
anymoteSender.sendKey (Code.BTN_MOUSE, Action.UP);

Mouse movement events are sent as MouseEvents.

Mouse wheel events are sent as MouseWheel events. The interpretation of mouse wheel events is left to the receiving application.

// Sends a mouse event to the server
message MouseEvent {
  // Relative movement of the cursor on the xAxis
  required int32 xDelta = 1;
  
  // Relative movement of the cursor on the yAxis
  required int32 yDelta = 2;
}

MouseWheel events

// Sends a mouse wheel to the server
message MouseWheel {
 // Relative movement of the cursor on the xAxis
 required int32 xScrollAmt = 1;
 
 // Relative movement of the cursor on the yAxis
 required int32 yScrollAmt = 2;
}

Data event

A Data event is used to send a sequence of keystrokes to Google TV. Currently, the protocol implementation on Google TV only supports type "com.google.tv.string" in this message. All other data types are rejected by Google TV with a "Unknown type" error.
// Sends a string and a type to interpret this string
message Data {
  // The type of data sent to the box. Currently the only value accepted for this is "com.google.tv.string"
  required string type = 1;

  // The sequence of keys to be sent.
  required string data = 2;
}

Fling events

Use a Fling event to send an Intent to Google TV to start an Activity associated with the specified Intent that is sent as a String. Convert the Intent object into a String by calling Intent.toUri(int), then add that String into a FlingEvent message. When Google TV receives the message, it creates an Intent from the message and passes it to the Android system by calling startActivity(). For example, the remote application could fling a Intent to play a YouTube video in the YouTube app on the Google TV:
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube://<video_id>");
anymoteSender.sendUrl (intent.toUri(Intent.URI_INTENT_SCHEME));
For ACTION_VIEW Intents for HTTP/HTTPS URIs, Google TV invokes the default handler which attempts to display the URI in the Chrome brower.
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://<webpage_url>");
anymoteSender.sendUrl (intent.toUri(Intent.URI_INTENT_SCHEME));

The client can send a sequence number along with a fling request. (The sequence is sent in the RemoteMessage message). The response from Google TV includes the sequence number that was sent in the request, enabling the client to match the result with the request.

message Fling {
  // URI to fling to Google TV
  required string uri = 1;
}

Fling results

When a fling event is sent, Google TV sends back a fling result in the ResponseMessage.

message FlingResult {
  enum Result {
    SUCCESS = 0;
    FAILURE = 1;
  }
 
  // Status
  required Result result = 1;
}

Monitoring the Connection

An application might want to ping Google TV to determine the status of the connection to the server even before it receives a TCP timeout. To do this, the application can send a RequestMessage that sets the sequence_number field but requires no response. If the connection is live, Google TV responds with a ResponseMessage containing that sequence_number.

When Google TV receives a message with a sequence_number field, it collects all the immediately available results for the requests requiring results, puts them in the ResponseMessage, and sends back with sequence numbers taken from RequestMessage. If no request of the RequestMessage requires response, but the sequence number is set, the ResponseMessage with the sequence number is sent back.

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.