This license governs use of the accompanying software ("Software"), and your use of the Software constitutes acceptance of this license.

Subject to the restrictions below, you may use the Software for any commercial or noncommercial purpose, including distributing derivative works.

SECTION 1: DEFINITIONS

A. "Syntactix LLC" refers to Syntactix, LLC, a limited liability corporation organized and operating under the laws of the state of Florida.

B. "Metrix" or "Metrix Library" refers to the Metrix Library WebOS Framework, which is a Syntactix LLC software product.

C. "SOFTWARE" refers to the source code, compiled binaries, installation files documentation and any other materials provided by Syntactix LLC.

SECTION 2: LICENSE

You agree that:

A. Subject to the terms of this license, the Licensor grants you a non-transferable, non-exclusive, worldwide, royalty-free copyright license to reproduce and redistribute unmodified the SOFTWARE for use within your Palm WebOS application provided that the following conditions are met:
(i) All copyright notices are retained.
(ii) A copy of this license is retained in the header of each source file of the software.

B. You may NOT decompile, disassemble, reverse engineer or otherwise attempt to extract, generate or retrieve source code from any compiled binary provided in the SOFTWARE.

C. You will (a) NOT use Syntactix's name, logo, or trademarks in association with distribution of the SOFTWARE or derivative works unless otherwise permitted in writing; and (b) you WILL indemnify, hold harmless, and defend Syntactix from and against any claims or lawsuits, including attorneys fees, that arise or result from the use or distribution of your modifications to the SOFTWARE and any additional software you distribute along with the SOFTWARE.

D. The SOFTWARE comes "as is", with no warranties. None whatsoever. This means no express, implied or statutory warranty, including without limitation, warranties of merchantability or fitness for a particular purpose or any warranty of title or non-infringement.

E. Neither Syntactix LLC nor its suppliers will be liable for any of those types of damages known as indirect, special, consequential, or incidental related to the SOFTWARE or this license, to the maximum extent the law permits, no matter what legal theory its based on. Also, you must pass this limitation of liability on whenever you distribute the SOFTWARE or derivative works.

F. If you sue anyone over patents that you think may apply to the SOFTWARE for a person's use of the SOFTWARE, your license to the SOFTWARE ends automatically.

G. The patent rights, if any, granted in this license only apply to the SOFTWARE, not to any derivative works you make.

H. The SOFTWARE is subject to U.S. export jurisdiction at the time it is licensed to you, and it may be subject to additional export or import laws in other places. You agree to comply with all such laws and regulations that may apply to the SOFTWARE after delivery of the SOFTWARE to you.

I. If you are an agency of the U.S. Government, (i) the SOFTWARE is provided pursuant to a solicitation issued on or after December 1, 1995, is provided with the commercial license rights set forth in this license, and (ii) the SOFTWARE is provided pursuant to a solicitation issued prior to December 1, 1995, is provided with Restricted Rights as set forth in FAR, 48 C.F.R. 52.227-14 (June 1987) or DFAR, 48 C.F.R. 252.227-7013 (Oct 1988), as applicable.

J. Your rights under this license end automatically if you breach it in any way.

K. This license contains the only rights associated with the SOFTWARE and Syntactix LLC reserves all rights not expressly granted to you in this license.

© 2010 Syntactix, LLC. All rights reserved.

Metrix Library App Integration Steps

A typical WebOS SDK based app has the following file structure:

YourApp

app

assistants

models

views

images

javascript

resources

stylesheets

appinfo.json

framework_config.json

icon.png

index.html

miniicon.png

smallicon.png

sources.json

Your project may vary but this is the typical default structure for a WebOS app.

The MetrixLibrary.zip should decompress into the following file structure:

MetrixLibrary

images

Metrix

header-button.png

header-button-inverse.png

menu-icon-back-bnk.png

menu-icon-back-dwn.png

menu-icon-back.upp.png

menu-icon-forward-bnk.png

menu-icon-forward-dwn.png

menu-icon-forward-upp.png

app

models

metrix.js

metrixCore.js

asyncWrappers.js

views

metrix

displayBulletin-dialog.html

To use the Metrix Lbrary, you will need to incorporate these files into your project using the following locations:

Take the Metrix folder out of MetrixLibrary/images and place it into YourApp/images folder. You project should now look like this:

YourApp

images

Metrix

header-button.png

header-button-inverse.png

menu-icon-back-bnk.png

menu-icon-back-dwn.png

menu-icon-back.upp.png

menu-icon-forward-bnk.png

menu-icon-forward-dwn.png

menu-icon-forward-upp.png

Next take MetrixLibrary/app/models/metrix.js and MetrixLibrary/app/models/asyncWrappers.js and place it in YourApp/app/models. Your projects should now look like this:

YourApp

app

models

metrix.js

metrixCore.jx

asyncWrappers.js

Finally, take the metrix folder out of MetrixLibrary/app/views and place it into YourApp/app/views/. Your project should now look like this:

YourApp

app

views

metrix

displayBulletin-dialog.html

To review, your project should have the following valid paths:

YourApp

images

Metrix

header-button.png

header-button-inverse.png

menu-icon-back-bnk.png

menu-icon-back-dwn.png

menu-icon-back.upp.png

menu-icon-forward-bnk.png

menu-icon-forward-dwn.png

menu-icon-forward-upp.png

app

models

metrix.js

metrixCore.js

asyncWrappers.js

views

metrix

displayBulletin-dialog.html

You will now need to add the Metrix Library to your sources.json file. Add the following line to the sources.json file:

{"source": "app\/models\/metrix.js"},

{"source": "app\/models\/asyncWrappers.js"},

You are new ready to utilize the Metrix Library.

Hot Patch Technology

Metrix now uses a simplified version of our Hot Patch Technology that we will later release to developers. This means we can update Metrix from now on without have to have everyone push an update to their app and we can make sure everyone has the latest and greatest bug fixes.

Using the Metrix Library

The Metrix object needs to have global scope. You can do this by instantiating the object in your stage-assistant.js file or if using an app-assistant.js file place it there.

Example:

YourApp = {}; //Global Object

AppAssistant.prototype.setup = function()

{

YourApp.Metrix = new Metrix(); //Instantiate Metrix Library

.

.

.

}

You can now use the Metrix Library functions in your app.

Example:

YourApp.Metrix.functionNameToCall();

The Metrix Library Functions

NAME: postDeviceData(versionCtrl)

PARAMS: versionCtrl - Optional parameter that will cause Metrix to only update the device data when your app version changes or the WebOs build number changes.

RETURNS: n/a

DESCRIPTION: This function is used to send the anonymous device data to the Metrix server. This function is what is used to generate your apps metrics and should be called at each app startup. It will record the following: device id, company name, app id, app version, WebOS build number, WebOS version, screen resolution, device name, carrier, and locale.

EXAMPLE:

YourApp.Metrix.postDeviceData();

NAME: isExpired(currentUtcTime, daysAllowed)

PARAMS: currentUtcTime - The time to calculate the expiration from in UTC.

daysAllowed - Number of days allowed before the function returns true.

RETURNS: Boolean - true if expired and false if not.

DESCRIPTION: This method will determine if an app is being used within the alloted window. The developer needs to specify the current time in UTC format and the number of days that the app should expire in from first use. The function will then compare the passed in UTC time to see if it is within the apps first run time stamp and the number of alloted days and return true if it is passed or false if it is within the alloted time. If the Metrix Library has no reference to the app's first run time stamp, then it will create it at that time. Remember that a POST is done everytime this function is called unless you pass in true, so try to only call in once on app start up.

EXAMPLE:

//check for expiration

this.controller.serviceRequest('palm://com.palm.systemservice/time', {

method: 'getSystemTime',

parameters: {},

onSuccess: function(response)

{

if(Mojo.appInfo.id == "com.domain.trial.yourapp")

{

if(YourApp.Metrix.isExpired(response.utc, 7))

{

this.controller.showAlertDialog({

onChoose: function(value)

{

Mojo.Controller.getAppController().closeAllStages();

},

title: $L("YourApp Trial Expired"),

message: $L("We are sorry but your trial version has expired. Click <a href='http://developer.palm.com/appredirect/?packageid=com.domain.paid.yourapp'>HERE</a> to visit the App Catalog to purchase the full version."),

choices:[

{label:$L("OK"), value:""}

]

});

}

}}.bind(this),

onFailure: function(){return;}

});

NAME: checkBulletinBoard(controller, minBulletinVersion, forceReview)

PARAMS: controller - Reference to the scene controller. Often it will be "this.controller"

minBulletinVersion - All bulletins with a version less than this will be ignored. This is usefull if notifing users of a new version so new users do not get notified.

forceReview - Optional boolean to tell the system to ingnore the minBulletinVersion and Time requirements. Often used to review bulletins after the user has dismissed them.

RETURNS: n/a

DESCRIPTION: This function will check the server every 24 hours for a new bulletin version. If the version of bulletin is greater than the minBulletinVersion passed in, a dialog box will be presented to the user. This dialog box is scrollable and allows the user to page through multiple bulletins. The user can dismiss the bulliten so it will not show up again or snooze it to be displayed during the next check (24 hours later). You can manage your bulletins through the web interface.

EXAMPLE:

YourApp.Metrix.checkBulletinBoard(this.controller, 1001);

NAME: customCounts (valueGroup, valueName, valueData)

PARAMS: valueGroup - The name of the collection of metrics.

valueName The label for the metric.

valueData The number to increment your count by. This number will be added the current count on the server.

RETURNS: Integer 0 Success, -1 Failure.

DESCRIPTION: This method will allow you to create a custom metric to count something. What you count is up to you! We ask that you try to cache the data as much as possible before calling this to post it to the server. Right now we enforce a 5 second speed limit on how fast you can call this function. This may be subject to change depending on how the server can handle things so be sure to check the return code to see if the call succeeded. A -1 indicates the call did not go through and you should cache the data and try again later.

EXAMPLE:

YouApp.Metrix.customCounts(MyCustomMetric, SomethingToCount, 2);

How to use asyncWrappers

asyncWrappers.js contains a wrapper class to protect your asynchronous service and Ajax calls from being garbage collected. This is based off of the work the Palm Facebook team has done. You can read about it here http://www.incaseofstairs.com/2010/04/garbage-collection-gotchas-in-webos/

To use the wrapper you will need to create a globally scope object for both the service and Ajax requests.

YourApp = {}; //Global Object

AppAssistant.prototype.setup = function()

{

YourApp.ServiceRequest = new ServiceRequestWrapper(); //Instantiate asynchronous service protection

YourApp.AjaxRequest = new AjaxRequestWrapper(); ////Instantiate ajax request protection

.

.

.

}

Now you will simply replace Mojo.Service.Request() or this.controller.serviceRequest() with YourApp.ServiceRequest.request(). These functions take the same parameters as the functions they are replacing.

For service calls where the subscription flag is set to TRUE, you are still responsible for calling YourApp.ServiceRequest.cancel(). The only exception is the download manager service, which the wrapper will auto handle once the download completes.

The same will be done with Ajax calls Ajax.Request() is replaced with YourApp.AjaxRequest.request().

Examples:

SERVICE REQUEST

this.controller.serviceRequest('palm://com.palm.systemservice/time', {

method: 'getSystemTime',

parameters: {},

onSuccess: this.handleTime.bind(this),

onFailure: function(){return;}

});

BECOMES

YourApp.ServiceRequest.request('palm://com.palm.systemservice/time', {

method: 'getSystemTime',

parameters: {},

onSuccess: this.handleTime.bind(this),

onFailure: function(){return;}

});

AJAX REQUEST

Ajax.Request.request(url, {

method: "get",

evalJSON: "false",

onSuccess: this.checkSuccess.bind(this),

onFailure: this.checkFailure.bind(this)

});

BECOMES

PrePackage.AjaxRequest.request(url, {

method: "get",

evalJSON: "false",

onSuccess: this.checkSuccess.bind(this),

onFailure: this.checkFailure.bind(this)

});