Confirmed users
483
edits
| Line 103: | Line 103: | ||
== 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. The permission model does not need to meet the real requirements for these apps. Also this use cases can probably be done with an unique keyword, different access rules and an agreed bidirectional API, but I just wanted a wider example) | ||
The lockscreen wants to be able to: | The lockscreen (Gaia System app) wants to be able to: | ||
* control the music played by the Gaia Music app | * control the music played by the Gaia Music app | ||
* display information about the currently played track from the Gaia Music app or any other 3rd party music | * display information about the currently played track from the Gaia Music app or any other 3rd party music app installed from the Firefox Marketplace. | ||
In order to receive information about the currently played music track, the System app needs to add the following 'connections' field to its manifest | In order to receive information about the currently played music track, the System app needs to add the following 'connections' field to its manifest | ||
| Line 116: | Line 116: | ||
'musictrack': { | 'musictrack': { | ||
'handler_path': 'musicmanager.html', | 'handler_path': 'musicmanager.html', | ||
'description': 'Show the currently played music track information in the lockscreen' | 'description': 'Show the currently played music track information in the lockscreen', | ||
'rules': { | |||
'installOrigin': ['marketplace.firefox.com'] | |||
} | |||
} | } | ||
} | } | ||
} | } | ||
where it advertises itself as able to receive connections through the 'musictrack' keyword, requested by | where it advertises itself as able to receive connections through the 'musictrack' keyword, requested by apps installed from the Firefox Marketplace and handled within the ''musicmanager.html'' page. | ||
On the other side, | On the other side, the Gaia Music app that wants to be controlled from the lockscreen (and only from there) should add the following 'connect' field to its manifest: | ||
{ | { | ||
'name': 'Music', | 'name': 'Music', | ||
/* ... */ | /* ... */ | ||
'connections': { | 'connections': { | ||
| Line 131: | Line 134: | ||
'description': 'Play, pause and stop music tracks', | 'description': 'Play, pause and stop music tracks', | ||
'rules': { | 'rules': { | ||
'origin': ['system.gaiamobile.org'] | |||
} | |||
} | |||
} | |||
} | |||
We also have a fictitious ''Songbirdy'' privileged app installed from the Firefox Marketplace and an also fictitious ''iTunos'' unprivileged app installed from an unknown source that want to be controlled by any privileged app. | |||
{ | |||
'name': 'Songbirdy', (or iTunos) | |||
/* ... */ | |||
'connections': { | |||
'musicremotecontrol': { | |||
'description': 'Play, pause and stop music tracks', | |||
'rules': { | |||
'minimumAccessLevel': 'privileged' | |||
} | } | ||
} | } | ||
| Line 138: | Line 157: | ||
=== Current track showed in the lockscreen === | === Current track showed in the lockscreen === | ||
Gaia Music 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) { | connect('musictrack').then(function onConnectionAccepted(ports) { | ||
// If the connection is allowed at least by one peer, the resolved callback | // If the connection is allowed at least by one peer, the resolved callback | ||
// will be triggered with a list of MessagePorts as parameter (ports in this case). | // will be triggered with a list of MessagePorts as parameter (ports in this case). | ||
ports.forEach(function(port) { | ports.forEach(function(port) { | ||
port.postMessage({ | // We still need to wait for the connected peer to notify as able to start | ||
// receiving messages through the port. | |||
port.onstart(function() { | |||
// At this point the Gaia Music app can start sending information about | |||
// the currently played track. | |||
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 messages sent from | |||
// the peer on the other side of the port. | |||
port.onmessage = myMessageHandler; | |||
}); | }); | ||
}); | }); | ||
}, function onConnectionRejected(reason) { | }, function onConnectionRejected(reason) { | ||
| Line 163: | Line 186: | ||
}); | }); | ||
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: | The System app only allows connections with apps installed from the Firefox Marketplace (or from certified apps). In this case, the caller (Gaia Music app) is a certified app, so the connection request is allowed by the platform. Assuming that the lockscreen (System app) 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] | Do you want to allow ''Music'' (music.gaiamobile.org) to connect with ''System'' (system.gaiamobile.org) to ''Show the currently played music track information in the lockscreen''? [Allow|Deny] | ||
In case that there would be more than one app subscribed to the 'musictrack' keyword, a different UI with a list of these apps would have been shown. | In case that there would be more than one app subscribed to the 'musictrack' keyword, a different UI with a list of these apps would have been shown. | ||
| Line 171: | Line 194: | ||
There is no need to show this UI again unless a new app subscribing to 'musictrack' is installed. | There is no need to show this UI again unless a new app subscribing to 'musictrack' is installed. | ||
The user allows the connection and a system message is sent to the lockscreen. | The user allows the connection and a system message is sent to the lockscreen (System app). | ||
navigator.setMessageHandler('connection', function(connectionRequest) { | navigator.setMessageHandler('connection', function(connectionRequest) { | ||
| Line 177: | Line 200: | ||
return; | return; | ||
} | } | ||
let port = connectionRequest.port; | |||
port.onmessage = onMusicTrackHandler; | |||
port.start(); | |||
}); | }); | ||
A similar connection request coming from Sonbirdy would also be | A similar connection request coming from Sonbirdy would also be allowed by the platform, cause we said that this app was installed from the Firefox Marketplace. However a connection request coming from iTunos would be rejected by the platform, since this app is unprivileged web content installed from an unknown source non listed within the lockscreen app rules. This request will not trigger any system messages and so the receiver won't ever be awake because of it (in this case the receiver (System app) is already live though). | ||
=== Music controls in the lockscreen === | === Music controls in the lockscreen === | ||
The | The lockscreen, in this example, wants to control '''only''' (no reasons, just an example) the music from the Gaia Music app (known origin). Once the lockscreen is ready, it sends a connection request of this kind: | ||
connect('musicremotecontrol').then((function onConnectionAccepted(ports) { | connect('musicremotecontrol').then((function onConnectionAccepted(ports) { | ||
| Line 197: | Line 217: | ||
return; | return; | ||
} | } | ||
let musicPort = ports[0]; | let musicPort = ports[0]; | ||
this.madeUpPlayButton.onclick = function() { | musicPort.onstart(function() { | ||
this.enableControlButtons(); | |||
this.madeUpPlayButton.onclick = function() { | |||
musicPort.postMessage({ | |||
action: 'play' | |||
}); | |||
}; | |||
this.madeUpPauseButton.onclick = function() { | |||
musicPort.postMessage({ | |||
action: 'pause' | |||
}); | |||
}; | |||
this.madeUpStopButton.onclick = function () { | |||
}); | musicPort.postMessage({ | ||
}; | action: 'stop' | ||
}); | |||
}; | |||
}); | |||
musicPort.onstop(function() { | |||
this.disableControlButtons(); | |||
}); | |||
}, function onConnectionRejected(reason) { | }, function onConnectionRejected(reason) { | ||
... | ... | ||
| Line 220: | Line 246: | ||
}).bind(this)); | }).bind(this)); | ||
If no previous connection through the 'musicremotecontrol' keyword between the | If no previous connection through the 'musicremotecontrol' keyword between the lockscreen and the Gaia Music app has been previously allowed an UI is shown to the user with a message like: | ||
'Do you want to allow System to communicate with Music to Play, pause and stop music tracks? [Accept|Reject]' | 'Do you want to allow ''System'' (system.gaiamobile.org) to communicate with ''Music'' (music.gaiamobile.org) to ''Play, pause and stop music tracks''? [Accept|Reject]' | ||
Even if Songbirdy and iTunos advertise themselves as able to connect through the 'musicremotecontrol' keyword, as the request is done with a specific rule that requires the receiver to have the 'music.gaiamobile.org' origin, these apps won't be listed in the above UI and won't receive any connection request. | Even if ''Songbirdy'' and ''iTunos'' advertise themselves as able to connect through the 'musicremotecontrol' keyword, as the request is done with a specific rule that requires the receiver to have the 'music.gaiamobile.org' origin, these apps won't be listed in the above UI and won't receive any system message with a connection request. | ||
The user allows that connection and a system message is sent to the Music app | The user allows that connection and a system message is sent to the Music app. | ||
navigator.setMessageHandler('connection', function(connectionRequest) { | navigator.setMessageHandler('connection', function(connectionRequest) { | ||
if ( | let keyword = connectionRequest.keyword; | ||
if (keyword != 'musictrack' || | |||
keyword != 'musicremotecontrol') { | |||
return; | return; | ||
} | } | ||
let port = connectionRequest.port; | |||
switch(keyword) { | |||
case 'musictrack': | |||
port.onmessage = this.onMusicTrackHandler; | |||
break; | |||
case 'musicremotecontrol': | |||
port.onmessage = this.onMusicRemoteControlHandler; | |||
break; | |||
} | } | ||
port.start(); | |||
}); | }); | ||