Bug 776027 - Allow nsIActivityUIGlueCallback to handle native and web activities. r=fabrice

This commit is contained in:
Josh Dover 2014-04-25 16:29:00 +02:00
parent e711f0be5e
commit ccfb78f771
3 changed files with 95 additions and 54 deletions

View File

@ -48,7 +48,8 @@ ActivitiesDialog.prototype = {
return;
SystemAppProxy.removeEventListener("mozContentEvent", act_getChoice);
activity.callback.handleEvent(evt.detail.value !== undefined
activity.callback.handleEvent(Ci.nsIActivityUIGlueCallback.WEBAPPS_ACTIVITY,
evt.detail.value !== undefined
? evt.detail.value
: -1);
});
@ -57,6 +58,12 @@ ActivitiesDialog.prototype = {
},
chooseActivity: function ap_chooseActivity(aOptions, aActivities, aCallback) {
// B2G does not have an alternate activity system, make no choice and return.
if (aActivities.length === 0) {
aCallback(Ci.nsIActivityUIGlueCallback.WEBAPPS_ACTIVITY, -1);
return;
}
this.activities.push({
name: aOptions.name,
list: aActivities,

View File

@ -4,22 +4,42 @@
#include "nsISupports.idl"
[scriptable, function, uuid(7a16feb4-5a78-4589-9174-b728f26942e2)]
[scriptable, function, uuid(674b6e69-05f0-41da-aabd-4184ea85c9d8)]
interface nsIActivityUIGlueCallback : nsISupports
{
void handleEvent(in long choice);
/**
* The activity service should start the activity at the specified index.
*/
const short WEBAPPS_ACTIVITY = 0;
/**
* The activity service should deliver the specified result to the MozActivity callback.
*/
const short NATIVE_ACTIVITY = 1;
/**
* Called if the user picked an activitiy to launch.
* @param resultType Inidcates that {@code result} is an index or a native activity result.
* @param result If WEBAPPS_ACTIVITY, the index of the chosen activity. Send '-1' if no choice is made.
If NATIVE_ACTIVITY, the return value to be sent to the MozActivity.
*/
void handleEvent(in short resultType, in jsval result);
};
/**
* To be implemented by @mozilla.org/dom/activities/ui-glue;1
*/
[scriptable, uuid(03e6743c-2fc3-43fa-bcb3-0476947c8ac5)]
[scriptable, uuid(3caef69f-3569-4b19-bcea-1cfb0fee4466)]
interface nsIActivityUIGlue : nsISupports
{
/**
* This method is called even if the size of {@code activities} is 0 so that the callee can
* decide whether or not to defer the request to an alternate activity system.
*
* @param options The ActivityOptions object in the form of { name: "send", data: { ... } }
* @param activities A json blob which is an array of { "title":"...", "icon":"..." }.
* @param onresult The callback to send the index of the choosen activity. Send -1 if no choice is made.
* @param callback The callback to send the index of the choosen activity, or the result.
*/
void chooseActivity(in jsval options, in jsval activities, in nsIActivityUIGlueCallback onresult);
void chooseActivity(in jsval options, in jsval activities,
in nsIActivityUIGlueCallback callback);
};

View File

@ -206,59 +206,73 @@ let Activities = {
let successCb = function successCb(aResults) {
debug(JSON.stringify(aResults));
// We have no matching activity registered, let's fire an error.
if (aResults.options.length === 0) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireError", {
"id": aMsg.id,
"error": "NO_PROVIDER"
});
delete Activities.callers[aMsg.id];
return;
}
function getActivityChoice(aResultType, aResult) {
switch(aResultType) {
case Ci.nsIActivityUIGlueCallback.NATIVE_ACTIVITY: {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireSuccess", {
"id": aMsg.id,
"result": aResult
});
break;
}
case Ci.nsIActivityUIGlueCallback.WEBAPPS_ACTIVITY: {
debug("Activity choice: " + aResult);
function getActivityChoice(aChoice) {
debug("Activity choice: " + aChoice);
// We have no matching activity registered, let's fire an error.
// Don't do this check until we have passed to UIGlue so the glue can choose to launch
// its own activity if needed.
if (aResults.options.length === 0) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireError", {
"id": aMsg.id,
"error": "NO_PROVIDER"
});
delete Activities.callers[aMsg.id];
return;
}
// The user has cancelled the choice, fire an error.
if (aChoice === -1) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireError", {
"id": aMsg.id,
"error": "ActivityCanceled"
});
delete Activities.callers[aMsg.id];
return;
}
// The user has cancelled the choice, fire an error.
if (aResult === -1) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireError", {
"id": aMsg.id,
"error": "ActivityCanceled"
});
delete Activities.callers[aMsg.id];
return;
}
let sysmm = Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
if (!sysmm) {
// System message is not present, what should we do?
delete Activities.callers[aMsg.id];
return;
}
let sysmm = Cc["@mozilla.org/system-message-internal;1"]
.getService(Ci.nsISystemMessagesInternal);
if (!sysmm) {
// System message is not present, what should we do?
delete Activities.callers[aMsg.id];
return;
}
debug("Sending system message...");
let result = aResults.options[aChoice];
sysmm.sendMessage("activity", {
"id": aMsg.id,
"payload": aMsg.options,
"target": result.description
},
Services.io.newURI(result.description.href, null, null),
Services.io.newURI(result.manifest, null, null),
{
"manifestURL": Activities.callers[aMsg.id].manifestURL,
"pageURL": Activities.callers[aMsg.id].pageURL
});
debug("Sending system message...");
let result = aResults.options[aResult];
sysmm.sendMessage("activity", {
"id": aMsg.id,
"payload": aMsg.options,
"target": result.description
},
Services.io.newURI(result.description.href, null, null),
Services.io.newURI(result.manifest, null, null),
{
"manifestURL": Activities.callers[aMsg.id].manifestURL,
"pageURL": Activities.callers[aMsg.id].pageURL
});
if (!result.description.returnValue) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireSuccess", {
"id": aMsg.id,
"result": null
});
// No need to notify observers, since we don't want the caller
// to be raised on the foreground that quick.
delete Activities.callers[aMsg.id];
if (!result.description.returnValue) {
Activities.callers[aMsg.id].mm.sendAsyncMessage("Activity:FireSuccess", {
"id": aMsg.id,
"result": null
});
// No need to notify observers, since we don't want the caller
// to be raised on the foreground that quick.
delete Activities.callers[aMsg.id];
}
break;
}
}
};