Services Overview

Services provide access to the core applications, hardware, and system services. There are two types of services:

  • Application services, which provide access to core applications, such as:
    • Launching URLs through the browser
    • Playing audio or video media
  • System services, which expose hardware-based services and low-level OS functions, such as:
    • Getting device orientation or streaming accelerometer data
    • Getting the current location or tracking location changes

Application services are a bit different from System services; for more information, read about Application Services below.

Accessing Services

All services are called asynchronously through the function serviceRequest, which takes two parameters: the URI of the service, and a JSON object containing parameters, callback functions, and other data needed in the service call. After the service runs, it returns a JSON result to the appropriate callback function depending on whether the call succeeded or failed. The callback function must parse the result data and handle it appropriately. Your application design should account for the possibility that a service may not return data immediately. Your application should keep running, and should not block the user from continuing to interact with the application while waiting for data to arrive.

There are two ways to call a service:

  • Use the scene controller's serviceRequest() method.
  • Create a service request object.

You should only create a request object if you need the subscription request to persist beyond the lifetime of the scene, or if you need to access services from outside a scene assistant — for example, in an application assistant or a stage assistant. When using a service request object, you are responsible for managing the object and destroying it when it is no longer needed.

It is generally preferable to use serviceRequest() because it allows the scene to manage the requests:

  • Requests with subscribe:true remain in memory until the scene is popped.
  • Other requests are removed from memory on completion.

If the scene is popped before the service request completes, the request is removed from memory and no result returns to the callback function.

Syntax

Using the scene controller's serviceRequest() method:

this.controller.serviceRequest('Service URI', JSON Object);

Creating a service Request Object:

Object = new Mojo.Service.Request('Service URI', JSON Object);

Service URI

The Service URI is the URI to the service, in the form:

palm://service name

Example:

palm://com.palm.connectionmanager

JSON Object

The JSON object includes the method to call on the service, the parameters to pass to that method, and the callback functions to register for the result.

Attribute
Example Description
method method: 'getstatus' The method to call on the service.
parameters parameters: {subscribe: true} Parameters to pass to the service method.
onSuccess onSuccess: this.handleResponse The callback function to call if the service request was successful.
onFailure onFailure: this.handleFailure The callback function to call if the service request failed.
onError onError: this.handleError The callback function to call if the service request resulted in an error.
onComplete onComplete: this.handleComplete The callback function to call if the service request is complete.

Example

this.controller.serviceRequest('palm://com.palm.connectionmanager', {
  method: 'getstatus',
  parameters:  {subscribe: true},
  onSuccess: this.handleResponse,
  onFailure: this.handleFailure
});

Response Handling

The framework calls this.handleResponse on a successful response, passing in a JSON object. Example:

Connectionmanager:
  { 
  "returnValue":true,
  "isInternetConnectionAvailable":true,
  "wifi":
      {
          "state": "connected",
          "ipAddress": "10.0.2.15",
          "ssid":"Emulator",
          "bssid":"Emulator"
      },
  "wan":
      {
          "state":"disconnected"
      },
  "btpan":
      {
          "state": "disconnected"
      }
  }

The callback function must process the response, taking appropriate action. For onFailure callbacks, typically there will be an errorText property containing a service-specific error string. See the individual Services for the expected errors.

Be sure to use .bind(this) when setting up your response callbacks to ensure that execution remains in the original scope when the callbacks are executed.

Service Notifications

Almost all services (other than those accessed through the Application Manager) allow the application to subscribe to notifications of service availability or unavailability. The meanings of these notifications are service-dependent and sometimes method-dependent. For example, the Connection Manager sends notifications on the gain/loss of a data connection over either of WiFi or WAN transports; the GPS service uses the notifications to send tracking updates.

Register by including a subscribe:true property in your parameters block when making a service request. Example:

this.controller.serviceRequest('palm://com.palm.connectionmanager', {
  method: 'getstatus',
  parameters: {
      subscribe: true
  },
  onSuccess: this.handleResponse
});

The callbacks come to the same onSuccess handler that receives the first response to the service request. All services direct notifications as well as the initial response to the onSuccess handler specified in the service request. Some services require different ways to register for notifications. For example, GPS registrations are made by setting the interval property to a non-zero value rather than using the subscribe property.

Application Services

Application services provide methods for accessing most core applications through the Application Manager service. The Application Manager chooses an appropriate handler based on the command and resource types specified by the request. The Application Manager provides two methods:

  • open — lets the Application Manager choose the appropriate handler based on the target resource passed in.

  • launch — directly requests a specific handler, passing in the appropriate application ID and parameter block.

In each case, it is up to the application to determine if it has been launched with the open method or the launch method, by inspecting the parameters passed to it. If the parameter object has the target property, the application has been invoked using the open method. Otherwise, it has been invoked with the launch method. It is up to each application to determine whether it supports execution via launch, open, or both. If an application supports the launch method, then it should document a list of parameters and their syntax/formats.

There is generally no return handling from Application Manager calls, so it is not necessary to specify callback functions with either method.

The open method

To let the Application Manager choose the appropriate handler based on the target resource, use the open method. The open method takes a resource encoded in a URI. The resource location and name, and any additional parameters, are appended per standard conventions.

Syntax:

this.controller.serviceRequest('palm://com.palm.applicationManager', {
  method: 'open',
  parameters:  {
      target: ''
  }
});

For example, to dial the phone, you would use:

this.controller.serviceRequest('palm://com.palm.applicationManager', {
  method:'open',
  parameters: {
      target: "tel://4085551234"
  }
});

or to get an unknown file from the web:

this.controller.serviceRequest('palm://com.palm.applicationManager', {
  method: 'open',
  parameters: {
      target:"http://www.domain.com/media/file.mp4
  }
)};

In each case, the Application Manager will route the request to the right application; in the latter case, it will download and route the file reference to the Video Player.

The launch method

When the appropriate application to handle the request is already known, or if it is inconvenient or inefficient to force the parameters into a URI format, use the launch method. The launch method takes an application ID and a JSON object containing launch parameters as key-value pairs.

Syntax:

this.controller.serviceRequest('palm://com.palm.applicationManager', {
  method: 'launch',
  parameters: {
      id: '',
      params: ''
  }
});

For examples of using Application Services, see the Application Manager API.

Cross-App Launch

Application Manager calls launch the targeted application into a new card. To preserve the context of the current application and speed up the transition, you can use a cross-app launch, in which the targeted application is launched using pushScene instead of a call to the Application Manager. For example, to bring up the Camera, you could make the following call:

this.someAssistant.getStageController().pushScene(
  { appId: 'com.palm.app.camera', name: 'capture' },
  { sublaunch: true }
);

Control will be returned back to your scene when the Camera finishes. You can do response handling in the activate method. Refer to the Services API for specific information about each service.

Unsubscribing from a Service

When you are ready to unsubscribe from a Service, use the cancel() method on the service request object.

var myRequest = this.controller.serviceRequest({ subscribe: true });
...
myRequest.cancel(); // Kills the subscription