Confirmed users
483
edits
(Created page with "= Description = This proposal is just a tweaked version of the [https://wiki.mozilla.org/WebAPI/Inter_App_Communication Inter App Communication API]. Its description, intend ...") |
No edit summary |
||
Line 11: | Line 11: | ||
// that allowed the connection. | // that allowed the connection. | ||
// If no peer is allowed to connect with the app, the Promise will | // If no peer is allowed to connect with the app, the Promise will | ||
// be rejected. | // be rejected with the reason of the rejection. | ||
Promise connect(DOMString keyword, | Promise connect(DOMString keyword, jsval rules); | ||
// The returned Future will contain ''true'' if at least a peer is allowed | // The returned Future will contain ''true'' if at least a peer is allowed | ||
Line 25: | Line 25: | ||
* ''keyword'' is the key string subject of the connection. Only apps advertising themselves as able to connect through this keyword will receive a connection request (if the user allows to and the app fulfills the requirements specified in the ''rules'' argument). | * ''keyword'' is the key string subject of the connection. Only apps advertising themselves as able to connect through this keyword will receive a connection request (if the user allows to and the app fulfills the requirements specified in the ''rules'' argument). | ||
* ''rules'' is an object containing a set of constraints for the requested connection. Only apps fulfilling these constraints will receive a connection request. These rules may contain: | * ''rules'' is an object containing a set of constraints for the requested connection. Only apps fulfilling these constraints will receive a connection request. These rules may contain: | ||
** ''minimumAccessLevel'' is the minimum level of access (one of https://developer.mozilla.org/en-US/docs/Web/Apps/Manifest#type) that the receiver app requires in order to be able to receive the connection request. | ** ''minimumAccessLevel'' is the minimum level of access (one of https://developer.mozilla.org/en-US/docs/Web/Apps/Manifest#type) that the receiver app requires in order to be able to receive the connection request. The default value will be 'web'. | ||
** ''origin'' (array) can be used to set specific | ** ''origin'' (array) can be used to set specific receivers by a list of origins. | ||
** ''developer'' (array) list of objects identifying app authors whose apps are allowed to receive a connection request. | ** ''developer'' (array) list of objects identifying app authors whose apps are allowed to receive a connection request. | ||
Line 39: | Line 38: | ||
'keyword1': { | 'keyword1': { | ||
'handler_path': '/handler1.html', | 'handler_path': '/handler1.html', | ||
'description': 'Do something for keyword1 connection' | 'description': 'Do something for keyword1 connection', | ||
'deferQueue': true | |||
}, | }, | ||
'keyword2': { | 'keyword2': { | ||
Line 53: | Line 53: | ||
* ''handler_path'' is the path of the page where the handler of the connection request lives in the app's code. If 'handling_path' is absent, the 'launch_patch' will be taken as default. | * ''handler_path'' is the path of the page where the handler of the connection request lives in the app's code. If 'handling_path' is absent, the 'launch_patch' will be taken as default. | ||
* ''description'' is the message to be shown to the user during the connection request that should describe why the connection is required and what does the app intends to do within that connection. | * ''description'' is the message to be shown to the user during the connection request that should describe why the connection is required and what does the app intends to do within that connection. | ||
* ''defer'' is a flag to allow apps to be woken up because of a connection request. If 'defer' is not present, it will default to true. The 'defer' value will be ignored if the connection has not being previously accepted by the receiver and the | * ''defer'' is a flag to allow apps to be woken up because of a connection request. If 'defer' is not present, it will default to true. The 'defer' value will be ignored if the connection has not being previously accepted by the user and the receiver which will be woken up so it can handle and properly accept the connection request. | ||
* ''deferQueue'' is a flag that indicates if an app expects to keep a queue of messages received while it is not being executed or has no handler for the messages. An app may choose to ignore messages sent to it while it is not being executed. If ''deferQueue'' is not present, false will be taken as the default value. | |||
=== Connection acknowledgement === | === Connection acknowledgement === | ||
Line 61: | Line 62: | ||
MessagePort port; | MessagePort port; | ||
DOMString keyword; | DOMString keyword; | ||
jsval callerInfo; | |||
void reject(); | |||
}; | }; | ||
Line 70: | Line 72: | ||
* ''callerInfo'' is an object containing basic information about the app requesting the connection channel. This information will allow the receiver to decide if the connection is secure enough or not. It may contain the following data ('''TODO:''' we need to decide which data do we want to provider. We might want to provide the whole caller app manifest): | * ''callerInfo'' is an object containing basic information about the app requesting the connection channel. This information will allow the receiver to decide if the connection is secure enough or not. It may contain the following data ('''TODO:''' we need to decide which data do we want to provider. We might want to provide the whole caller app manifest): | ||
** ''origin'' which is the origin of the app requesting the connection. | ** ''origin'' which is the origin of the app requesting the connection. | ||
** ''accessLevel'' which is the [https://developer.mozilla.org/en-US/docs/Web/Apps/Manifest#type access level] of the app requesting the connection. | ** ''accessLevel'' which is the [https://developer.mozilla.org/en-US/docs/Web/Apps/Manifest#type access level] of the app requesting the connection. | ||
** ''developer'' which contains the information about the developer of the app requesting the connection. It may contain the name and url of the developer. | ** ''developer'' which contains the information about the developer of the app requesting the connection. It may contain the name and url of the developer. | ||
Line 79: | Line 80: | ||
interface MessagePort { | interface MessagePort { | ||
void postMessage(...); | void postMessage(...); | ||
attribute | attribute jsval onmessage; | ||
}; | }; | ||
= Defer mechanism = | = Defer mechanism = | ||
Line 90: | Line 91: | ||
== Lockscreen and Music == | == Lockscreen and Music == | ||
(Disclaimer: this is just a rough example of a possible solution for this use case) | (Disclaimer: this is just a rough example of a possible solution for this use case. This can probably be done with an unique keyword and an agreed bidirectional API, but I wanted a wider example) | ||
The lockscreen wants to be able to control the music played by the Gaia Music app or any other 3rd party music app | The lockscreen wants to be able to control the music played by the Gaia Music app or any other 3rd party music app and also wants to display information about the currently played track from any of these music apps if they are | ||
In order to receive information about the currently played music track, the System app needs to add the following 'connect' field to its manifest | In order to receive information about the currently played music track, the System app needs to add the following 'connect' field to its manifest | ||
Line 118: | Line 119: | ||
} | } | ||
} | } | ||
=== Current track showed in the lockscreen === | |||
The Gaia Music app starts playing a random track and wants to share the information about this track with other apps. Since the shared information is harmless, it doesn't care about the receiver, so no rules are required while requesting the connection. | |||
connect('musictrack').then(function onConnectionAccepted(ports) { | |||
// If the connection is allowed at least by one peer, the resolved callback | |||
// will be triggered with a list of MessagePorts as paramater (ports in this case). | |||
// At this point the Gaia Music app can start sending information about | |||
// the currently played track. | |||
ports.forEach(function(port) { | |||
port.postMessage({ | |||
title: 'The Beatles', | |||
artist: 'Strawberry fields forever' | |||
}); | |||
// In this example approach, we probably don't need a bidirectional communication | |||
// as we have that through a different keyword, but we can always set a message | |||
// handler via MessagePort.onmessage at this point to handle the message sent from | |||
// the peer on the other side of the port. | |||
port.onmessage = myMessageHandler; | |||
}); | |||
}, function onConnectionRejected(reason) { | |||
// If there is no peer that connects with the 'musictrack' keyword, the user | |||
// didn't allow the connection with at least one peer or all the peers rejected | |||
// the connection, the reject callback will be triggered. | |||
... | |||
}); | |||
Assuming that the lockscreen is the only application advertising itself as able to connect through the 'musictrack' keyword and there is no record of a previously allowed connection between this two apps through this keyword, a popup will be shown to the user saying something like: | |||
Do you want to allow ''Music'' to connect with ''System'' to ''Show the currently played music track information in the lockscreen''? [Allow|Deny] | |||
The user allows the connection and a system message is sent to the lockscreen. The lockscreen only allows connections with privileged apps, so it checks that in the connection request handler, and set a handler for the messages sent through the MessagePort via ''MessagePort.onmessage'' | |||
navigator.setMessageHandler('connect', function(connectionRequest) { | |||
if (connectionRequest.keyword !== 'musictrack') { | |||
return; | |||
} | |||
if (connectionRequest.callerInfo.accessLevel !== 'web') { | |||
connectionRequest.port.onmessage = onMusicTrackHandler; | |||
} | |||
}); | |||
=== Music controls in the lockscreen === | |||
Assuming that the three example music apps are installed, once the lockscreen is ready it sends a connection request of this kind: | |||
connect('musicremotecontrol').then(function onConnectionAccepted(ports) { | |||
}, function onConnectionRejected(reason) { | |||
}); | |||
meaning that the lockscreen wants to connect | |||
'''TODO''' | '''TODO''' | ||
Line 133: | Line 189: | ||
Promise getSubcriptionMessages(DOMString keyword); | Promise getSubcriptionMessages(DOMString keyword); | ||
}; | }; | ||
* Do we want to expose app access level as a enum, so the developer can do something like | |||
if (connectionRequest.callerInfo.accessLevel <= PRIVILEGED) { //whatever } | |||
* It would be great if apps could also filter by install origin, but certified apps has not a clear install origin. |