Activity Manager
The Activity Manager service (com.palm.activitymanager) acts as a traffic cop for Activities (apps, services, tasks, network flows, etc.) running on the device, balancing Activity priorities and system resources to optimize the user's experience.
See also
Methods
- adopt - Adopt an Activity, registering willingness to take over as parent.
- cancel - End an Activity immediately, allowing little or no time for clean-up.
- complete - End an Activity with option to restart with new attributes.
- create - Create an Activity.
- getDetails - Get details about an Activity, including associations.
- monitor - Get Activity state, with option to subscribe to future updates.
- release - Allows parent to end an Activity, allowing time for adopters to take over as the parent and let the Activity continue.
- start - Starts an Activity, with an option to force it to run.
- stop - End an Activity, allowing some time for clean-up.
adopt
Registers an app's or service's willingness to take over as the Activity's parent.
If your app can wait for an unavailable Activity (not released) to become available, then set the "wait" flag to true. If it is, and the Activity is valid (exists and is not exiting), the call should succeed. If it cannot wait, and the Activity is valid but cannot be adopted, then the call fails. The adopted return flag indicates a successful or failed adoption.
If not immediately adopted and waiting is requested, the "orphan" event informs the adopter that they are the new Activity parent.
An example where adoption makes sense is an app that allocates a separate Activity for a sync, and passes that Activity to a service to use. The service should adopt the Activity and be ready to take over in the event the app exits before the service is done syncing. Otherwise, it receives a "cancel" event and should exit immediately. The service should wait until the adopt (or monitor) call returns successfully before beginning Activity work. If adopt or monitor fails, it indicates the caller has quit or closed the Activity and the request should not be processed. The Service should continue to process incoming events on their subscription to the Activity.
If the service did not call adopt to indicate to the Activity Manager its willingness to take over as the parent, it should be prepared to stop work for the Activity and unsubscribe if it receives a "cancel" event. Otherwise, if it receives the "orphan" event indicating the parent has unsubscribed and the service is now the parent, then it should use complete when finished to inform the Activity Manager before unsubscribing.
Syntax
{
"activityId" : int,
"activityName" : string,
"wait" : boolean,
"subscribe" : boolean,
"detailedEvents" : boolean
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this, or "activityName" is required. |
| activityName | No | string | Activity name. Either this, or "activityId" is required. |
| wait | Yes | boolean | Wait for Activity to be released flag. |
| subscribe | Yes | boolean | Flag to subscribe to Activity and receive Activity events. |
| detailedEvents | Yes | boolean | Flag to have the Activity Manager generate "update" events when the state of an Activity's requirement changes. |
Returns
{
returnValue : boolean,
adopted : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
| adopted | boolean |
true (adopted) or false (not adopted)
|
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "adopt",
parameters: {
"activityId" : 876,
"wait" : true,
"subscribe" : true,
"detailedEvents" : false
},
onSuccess: function(e){ Mojo.Log.info("adopt success, adopted="+e.adopted); },
onFailure: function(e){ Mojo.Log.info("adopt failure"); }
});
cancel
Terminates the specified Activity and sends a "cancel" event to all subscribers. This call should succeed if the Activity exists and is not already exiting.
This is different from the stop method in that the Activity should take little or no time to clean up. For example, this might matter for an email sync service that needs more time to finish downloading a large email attachment. On a "cancel", it should immediately abort the download, clean up, and exit. On a "stop", it should finish downloading the attachment in some reasonable amount of time, say, 10-15 seconds. Note, however, that specific time limits are not currently enforced, though this could change.
Syntax
{
"activityId" : int,
"activityName" : string
}
Parameter
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this, or "activityName" is required. |
| activityName | No | string | Activity name. Either this, or "activityId" is required. |
Returns
{
returnValue : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "cancel",
parameters: {"activityId": 17},
onSuccess: function(e) { Mojo.Log.info("cancel success");},
onFailure: function(e) { Mojo.Log.info("cancel failure");}
});
complete
An Activity's parent can use this method to end the Activity and optionally restart it with new attributes. If there are other subscribers, they are sent a "complete" event.
If restart is requested, the Activity is optionally updated with any new Callback, Schedule, Requirements, or Trigger data and returned to the queued state. Specifying false for any of those properties removes the property completely. For any properties not specified, current properties are used.
If the Activity is persistent (specified with the persist flag in the Type object), the db8 database is updated before the call returns.
Syntax
{
"activityId" : int | "activityName" : string,
"restart" : boolean,
"callback" : false | Callback,
"schedule" : false | Schedule,
"requirements" : false | Requirements,
"trigger" : false | Triggers,
"metadata: : false | any object
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this, or "activityName" is required. |
| activityName | No | string | Activity name. Either this, or "activityId" is required. |
| restart | No | boolean | Restart Activity flag. Default is false. |
| callback | No | boolean or Callback | Callback to use if Activity is restarted. |
| schedule | No | boolean or Schedule | Schedule to use if Activity is restarted. |
| requirements | No | boolean or Requirements | Prerequisites to use if Activity is restarted. |
| trigger | No | boolean or Trigger | Trigger to use if Activity is restarted. |
| metadata | No | boolean or any object | Meta data |
Returns
{
returnValue : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "complete",
parameters: {"activityId": 876},
onSuccess: function(){ Mojo.Log.info("complete success"); },
onFailure: function(){ Mojo.Log.info("complete failure"); }
});
create
Creates a new Activity and returns its ID.
You can create either a foreground or background Activity. A foreground Activity is run as soon as its specified prerequisites are met. After a background Activity's prerequisites are met, it is moved into a ready queue, and a limited number are allowed to run depending on system resources. Foreground is the default.
Activities can be scheduled to run at a specific time or when certain conditions are met or events occur.
Each of your created and owned Activities must have a unique name. To replace one of your existing Activities, set the "replace" flag to true. This cancels the original Activity and replaces it with the new Activity.
To keep an Activity alive and receive status updates, the parent (and adopters, if any) must set the "subscribe" flag to true. Otherwise, if the Activity is created with a callback and "subscribe=false", the Activity must be adopted immediately after the callback is invoked for the Activity to continue.
To indicate the Activity is fully-initialized and ready to launch, set the "start" flag to true. Activities with a callback should be started when created—the callback is invoked when the prerequisites have been met and, in the case of a background, non-immediate Activity, it has been cleared to run.
When requirements are not initially met
If the creator of the Activity also specifies "subscribe":true, and detailed events are enabled for that subscription, then the Activity Manager will generate either an immediate "start" event if the requirements are met, or an "update" event if the Activity is not yet ready to start due to missing requirements, schedule, or trigger. This allows the creating Service to determine if it should continue executing while waiting for the callback, or exit to free memory if it may be awhile before the Activity is ready to run.
Syntax
{
"activity" : Activity,
"subscribe" : boolean,
"detailedEvents" : boolean,
"start" : boolean,
"replace" : boolean
}
Parameters
| Argument | Required | Type | Description |
| activity | Yes | object | Activity object |
| subscribe | No | boolean | Subscribe to Activity flag. |
| detailedEvents | No | boolean | Flag to have the Activity Manager generate "update" events when the state of one of this Activity's requirements changes. |
| start | No | boolean | Start Activity immediately flag. |
| replace | No | boolean | Cancel Activity and replace with Activity of same name flag. |
Returns
{
returnValue : boolean,
activityId : number
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
| activityId | number | Activity ID. |
Examples
In this section:
- Create an Activity
- Create a Scheduled Activity
- Create a Triggered Activity
- Create an Activity with a Trigger and a Callback
- Create an Activity with a Keyed Trigger Based on a db8 Watch
Create an Activity
Create an Activity with a given name and description.
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "create",
parameters: {
"activity": {
"name": "basicactivity",
"description": "Test create",
"type": {
"foreground": true
},
"start": true,
"subscribe":true
},
onSuccess: function(e) { Mojo.Log.info("Success, results="+JSON.stringify(e.activityId));},
onFailure: function(e) { Mojo.Log.info("Failure, err="+JSON.stringify(e));}
});
Create a Scheduled Activity
This creates an Activity that receives a "start" event on the subscription when the specified time is reached. The Activity is started as part of the create command.
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "create",
parameters: {
"activity": {
"name": "ScheduledActivity",
"description": "Test create of scheduled activity",
"type": {"foreground": true}
},
"schedule" : { "start" : "2010-05-27 13:22:00" },
"start": true,
"subscribe":true
},
onSuccess: function(e) { Mojo.Log.info("Success, results="+JSON.stringify(e));},
onFailure: function(e) { Mojo.Log.info("Failure, err="+JSON.stringify(e) );}
});
Create a Triggered Activity
The following is an example of a basic Triggered Activity. The trigger is based on the connection status changing. An easy way to change the status is to switch into and out of airplane mode. After the initial success result, the second result causes the Trigger to fire.
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "create",
parameters: {
"activity": {
"name": "triggeredActivity",
"description": "Test create Activity with Trigger",
"type": {"background": true},
"trigger" : {
"method" : "palm://com.palm.connectionmanager/getStatus",
"params" : {"subscribe":true}
}
},
"start": true,
"subscribe": true
},
onSuccess: function(e) { Mojo.Log.info("Success, results="+JSON.stringify(e));},
onFailure: function(e) { Mojo.Log.info("Failure, err="+JSON.stringify(e) );}
});
Create an Activity with a Trigger and a Callback
The following example creates an Activity with a trigger and a callback. The trigger occurs when the device's connection status changes. When this occurs, the callback is invoked and the device's email service is launched to send an email.
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "create",
parameters: {
"activity": {
"name": "triggeredActivity",
"description" : "Example triggered Activity",
"type": { "background": true },
"trigger" : {
"method" : "palm://com.palm.connectionmanager/getStatus",
"params" : {"subscribe":true}
},
"callback" : {
"method" : "palm://com.palm.applicationManager/open",
"params" : {
id: "com.palm.app.email", // Send email
params: {
summary: "test subject",
text: "Test email text.",
recipients: [{
type: "email",
role: 1,
value:"Hal.Itosis@palm.com",
contactDisplay: "Ginger Vitis"
}]
}
}
}
},
"start" : true // Start immediately
},
onSuccess: function(e) { Mojo.Log.info("Success, results="+JSON.stringify(e));},
onFailure: function(e) { Mojo.Log.info("Failure, err="+JSON.stringify(e));}
});
Create an Activity with a Keyed Trigger Based on a db8 Watch
This example creates an activity with a keyed trigger and a callback. The trigger is based on a db8 watch method and query. If the results of the query change, the watch method invokes the callback function. The Activity Manager looks for the "fired" keyed property in the results that are returned. The query contains two where clauses indicating a specific account and a revision (_rev) field. The revision is a counter that is incremented every time a db8 JSON object changes and is stored with the object.
See the db8 documentation for more information on formatting queries.
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "create",
parameters: {
"activity": {
"callback": {
"method": "palm://com.palm.myservice/userEdit" },
"description": "my db watch",
"name": "My DbWatch",
"trigger": {
"key": "fired",
"method": "palm://com.palm.db/watch",
"params": {
"query": {
"from": "com.palm.contact:1",
"where": [
{ "prop": "accountId", "op": "=", "val": "21e2" },
{ "prop": "_rev", "op": ">", "val": 11410 }
],
"incDel": true
}
}
},
"type": { "background": true, "persist": true },
"requirements": { "idle": 30 }
},
"start": true
},
onSuccess: function(e) { Mojo.Log.info("Success, results="+JSON.stringify(e));},
onFailure: function(e) { Mojo.Log.info("Failure, err="+JSON.stringify(e));}
});
getDetails
Requests an Activity's full details, including associations.
Syntax
{
"activityId" : int,
"activityName" : string
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this or activityName must be specified. |
| activityName | No | string | Activity name. Either this or activityId must be specified. |
Returns
{
returnValue : boolean,
activity : [Activity] [Activity-Data-Type]
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure)
|
| activity | Activity | Activity object including associations. |
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "getDetails",
parameters: {"activityId": 3},
onSuccess: function(e) { Mojo.Log.info("getDetails success, activity="+JSON.stringify(e.activity));},
onFailure: function(e) { Mojo.Log.info("getActivity failure");}
});
monitor
Given an activity ID, returns the current activity state. If the caller chooses to subscribe, additional Activity status updates are returned as they occur.
Syntax
{
"activityId" : int,
"activityName" : string,
"subscribe" : boolean,
"detailedEvents" : boolean
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this, or "activityName" is required. |
| activityName | No | string | Activity name. Either this, or "activityId" is required. |
| subscribe | Yes | boolean | Activity subscription flag. |
| detailedEvents | Yes | boolean | Flag to have the Activity Manager generate "update" events when the state of one of this Activity's requirements changes. |
Returns
{
returnValue : boolean,
state : string
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
| state | string | Activity state |
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "monitor",
parameters: {
"activityId": 3,
"subscribe" : false,
"detailedEvents" : false
},
onSuccess: function(e) { Mojo.Log.info("Monitor success, state="+JSON.stringify(e.state));},
onFailure: function(e) { Mojo.Log.info("Monitor failure");}
});
release
Allows a parent to free an Activity and notify other subscribers. The Activity is cancelled unless one of its non-parent subscribers adopts it and becomes the new parent. This has to happen in the timeout specified. If no timeout is specified, the Activity is cancelled immediately. For a completely safe transfer, a subscribing app or service, prior to the release, should already have called adopt, indicating its willingness to take over as the parent.
Syntax
{
"activityId" : int,
"activityName" : string,
"timeout" : int
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this or "activityName" is required. |
| activityName | No | string | Activity name. Either this or "activityId" is required. |
| timeout | No | int | Time to wait, in seconds, for Activity to be adopted after release. |
Returns
{
returnValue : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure)
|
Example
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "release",
parameters: {
"activityId" : 876,
"timeout" : 30
},
onSuccess: function(){ Mojo.Log.info("release success"); },
onFailure: function(){ Mojo.Log.info("release failure"); }
});
start
Attempts to start the specified Activity, either moving it from the "init" state to be eligible to run, or resuming it if it is currently paused. This sends "start" events to any subscribed listeners once the Activity is cleared to begin. If the "force" parameter is present (and true), other Activities could be cancelled to free resources the Activity needs to run.
Syntax
{
"activityId" : int,
"activityName" : string,
"force" : boolean
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this or "activityName" is required. |
| activityName | No | string | Activity name. Either this or "activityId" is required. |
| force | No | boolean | Force the Activity to run flag. If "true", other Activities could be cancelled to free resources the Activity needs to run. |
Returns
{
returnValue : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "start",
parameters: {"activityId": 87644},
onSuccess: function(){ Mojo.Log.info("Start success"); },
onFailure: function(){ Mojo.Log.info("Start failure"); }
});
stop
Stops an Activity and sends a "stop" event to all Activity subscribers. This succeeds unless the Activity is already cancelled.
This is different from the cancel method in that more time is allowed for the Activity to clean up. For example, this might matter for an email sync service that needs more time to finish downloading a large email attachment. On a "cancel", it should immediately abort the download, clean up, and exit. On a "stop," it should finish downloading the attachment in some reasonable amount of time--say, 10-15 seconds.
Syntax
{
"activityId" : int,
"activityName" : string
}
Parameters
| Argument | Required | Type | Description |
| activityId | No | int | Activity ID. Either this or "activityName" is required. |
| activityName | No | string | Activity name. Either this or "activityId" is required. |
Returns
{
returnValue : boolean
}
| Argument | Type | Description |
| returnValue | boolean |
true (success) or false (failure).
|
Example
Mojo
this.controller.serviceRequest("palm://com.palm.activitymanager/", {
method: "stop",
parameters: {"activityId": 876},
onSuccess: function(e){ Mojo.Log.info("stop success"); },
onFailure: function(e){ Mojo.Log.info("stop failure"); }
});