You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cordova.apache.org by Filip Maj <fi...@adobe.com> on 2011/11/10 18:30:25 UTC

Change to Plugins introduced in Android

Hey all,

A while ago an issue came up on IRC regarding Media: if a phone received a phone call while a PhoneGap - er – Callback app was playing media, it wouldn't stop the media so you had music or whatever playing in the background during your phone call. Not ideal :)

I filed a bug for this on Android and Bryce slayed it, of course, but also came up with a pretty elegant solution to it. I would recommend the whole team check it out:

https://github.com/callback/callback-android/commit/0bbcf5cfd2349801d00e067424a66fa1086103ea

Plugins now can handle an onMessage event and can also broadcast a message to all other plugins. For example, on Android, a "telephony receiver" is registered on the app and when a phone call comes in or is hung up, a message is broadcast to all other plugins. The audio handler plugin will pause and resume all streams as phone calls come in / get hung up. Pretty nice!

A side effect for this latest commit is that the network plugin uses this approach to broadcast going online/offline to other plugins. Currently not used by other plugins but may be useful down the road.

The reason I'm posting this is because we want to keep our plugin interfaces aligned across platforms. It would be great if the other platforms implemented this as well. Also would love to hear what the rest of the team thinks of this change.

Re: Change to Plugins introduced in Android

Posted by Brian LeRoux <b...@brian.io>.
Seems very sensible to me.

On Thu, Nov 10, 2011 at 9:30 AM, Filip Maj <fi...@adobe.com> wrote:
> Hey all,
>
> A while ago an issue came up on IRC regarding Media: if a phone received a phone call while a PhoneGap - er – Callback app was playing media, it wouldn't stop the media so you had music or whatever playing in the background during your phone call. Not ideal :)
>
> I filed a bug for this on Android and Bryce slayed it, of course, but also came up with a pretty elegant solution to it. I would recommend the whole team check it out:
>
> https://github.com/callback/callback-android/commit/0bbcf5cfd2349801d00e067424a66fa1086103ea
>
> Plugins now can handle an onMessage event and can also broadcast a message to all other plugins. For example, on Android, a "telephony receiver" is registered on the app and when a phone call comes in or is hung up, a message is broadcast to all other plugins. The audio handler plugin will pause and resume all streams as phone calls come in / get hung up. Pretty nice!
>
> A side effect for this latest commit is that the network plugin uses this approach to broadcast going online/offline to other plugins. Currently not used by other plugins but may be useful down the road.
>
> The reason I'm posting this is because we want to keep our plugin interfaces aligned across platforms. It would be great if the other platforms implemented this as well. Also would love to hear what the rest of the team thinks of this change.
>

Re: Change to Plugins introduced in Android

Posted by Dave Johnson <da...@gmail.com>.
> Dave, doesn't the url overloading stuff really just ends being a
> declarative interface to the same code. ie, first write the programmatic
> interface, then wrap/map the declarative interface to it?

yes for sure.

Re: Change to Plugins introduced in Android

Posted by Jesse <pu...@gmail.com>.
Sounds like we are trying to write cross-device native plugins. IMO
The 'mechanism' that we use will likely differ from platform to platform,
as it should.

I think that simply defining the fact that native plugins need to listen
for 'interuptionEvents' or 'eventNotifications' or explicit calls to
their 'onMessage'
method should be enough. ( generally I prefer a subscriber model though )

I think it is more important to define the types of
interruptions/events that can occur, and make sure they are all handled.
 ie.
MemoryLow, BatteryLow, DisplayOff, IncomingCall, ...

I am still not completely sold on having this go through our own global
dispatcher.  All platforms already have this mechanism at some level, so it
should already be available to native code in the plugin.

Dave, doesn't the url overloading stuff really just ends being a
declarative interface to the same code. ie, first write the programmatic
interface, then wrap/map the declarative interface to it?

On Mon, Nov 21, 2011 at 1:50 PM, Filip Maj <fi...@adobe.com> wrote:

> So what would be required in that? Just a specification for the data
> object that is passed to onMessage ?
>
> On 11-11-21 1:47 PM, "Dave Johnson" <da...@gmail.com> wrote:
>
> >I like the idea of a messaging API but the first thing that came to my
> >mind was that we should be using a generic mechanism like web intents
> >for this.
> >
> >On Android we have the ability configure a plugin such that the
> >onOverrideUrlLoading(String url) method is called (handleOpenUrl I
> >think on iOS) when a URL is loaded that matches (could be regex or
> >whatever) one that is listed in the plugin configuration xml / plist.
> >
> >This is also a common way to communicate on most platforms. iOS of
> >course supports the handling of specific URIs and intents on Android
> >are pretty much the same thing.
> >
> >Thoughts?
> >
> >-dave
> >
> >
> >On Mon, Nov 21, 2011 at 1:06 PM, Filip Maj <fi...@adobe.com> wrote:
> >>
> >>
> >> On 11-11-16 1:47 PM, "Patrick Mueller" <pm...@gmail.com> wrote:
> >>
> >>>On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:
> >>>
> >>>> The reason I'm posting this is because we want to keep our plugin
> >>>> interfaces aligned across platforms. It would be great if the other
> >>>> platforms implemented this as well. Also would love to hear what the
> >>>>rest
> >>>> of the team thinks of this change.
> >>>>
> >>>
> >>>I like the concept, but think perhaps the API could be changed a bit.
> >>>
> >>>Suggest that Plugins can implement a method Plugin::onMessage(String id,
> >>>Object data) as suggested, which will be invoked when a message is
> >>>"posted".  In addition, Plugins implement (via superclass) a method
> >>>Plugin::postMessage(String id, Object data).  Looks like it's currently
> >>>called onMessage() and implemented on PluginManager.  Why expose another
> >>>class (PluginManager) when we can put this in the Plugin itself?  And
> >>>why
> >>>call an API that sends a message "onMessage".
> >>
> >> Agree with this. Keep it to the Plugin interface and name it
> >>postMessage.
> >>
> >>>We should agree on the synchroncity of postMessage() and onMessage()
> >>>invocations and document them in the source comments.  Does
> >>>postMessage()
> >>>not return until all plugins are sent onMessage()?  Or are these
> >>>asynchronous?  I think synchronous makes sense, and then we should
> >>>document
> >>>that onMessage() invocations are blocking the main thread, so shouldn't
> >>>do
> >>>long-running tasks.
> >>
> >> Conceptually I think this is no different than making a call into
> >>plugins
> >> from JS. I would lean towards async mechanics. Some plugins may need to
> >>do
> >> long-running tasks when handling messages. This kind of reminds me of
> >>the
> >> discussion we had initially about plugins, whether they are sync/async.
> >>We
> >> quickly realized that async is the way to go. The project in incubation
> >>is
> >> called callback, after all ;)
> >>
> >>>Rather than send every event to every plugin, perhaps plugins should
> >>>indicate that they wish to receive events.  Another API perhaps:
> >>>Plugin::listenForMessages(boolean).  Don't listen, we won't send
> >>>messages.
> >>> Not sure it's worth it.
> >>
> >> +1; set this to false as default and then plugin authors can change +
> >> implement onMessage/postMessage when they need it.
> >>
> >>>
> >>>We should consider how the id's should be namespaced.
> >>>
> >>>We should be documenting for each plugin which id's they send and
> >>>respond
> >>>to.  Doesn't need to be in the user docs (obviously), but does need to
> >>>be
> >>>documented somewhere.  I guess code comments will be good enough for
> >>>now.
> >>
> >> Good enough for now, maybe something that should be discussed once we
> >>get
> >> into plugin packaging.
> >>
> >>>
> >>>In terms of the naming of the APIs themselves, there may be some
> >>>confusion
> >>>as folks may confuse these names with ones available in the DOM (eg,
> >>>https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
> >>>suggestion, which I'm not immediately happy with, is to stuff the string
> >>>"Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
> >>>dunno, maybe not so horrible.
> >>
> >> A bit more verbose, not a big deal I think. Either way works IMO.
> >>
> >>>
> >>>--
> >>>Patrick Mueller
> >>>http://muellerware.org
> >>
> >>
>
>

Re: Change to Plugins introduced in Android

Posted by Filip Maj <fi...@adobe.com>.
So what would be required in that? Just a specification for the data
object that is passed to onMessage ?

On 11-11-21 1:47 PM, "Dave Johnson" <da...@gmail.com> wrote:

>I like the idea of a messaging API but the first thing that came to my
>mind was that we should be using a generic mechanism like web intents
>for this.
>
>On Android we have the ability configure a plugin such that the
>onOverrideUrlLoading(String url) method is called (handleOpenUrl I
>think on iOS) when a URL is loaded that matches (could be regex or
>whatever) one that is listed in the plugin configuration xml / plist.
>
>This is also a common way to communicate on most platforms. iOS of
>course supports the handling of specific URIs and intents on Android
>are pretty much the same thing.
>
>Thoughts?
>
>-dave
>
>
>On Mon, Nov 21, 2011 at 1:06 PM, Filip Maj <fi...@adobe.com> wrote:
>>
>>
>> On 11-11-16 1:47 PM, "Patrick Mueller" <pm...@gmail.com> wrote:
>>
>>>On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:
>>>
>>>> The reason I'm posting this is because we want to keep our plugin
>>>> interfaces aligned across platforms. It would be great if the other
>>>> platforms implemented this as well. Also would love to hear what the
>>>>rest
>>>> of the team thinks of this change.
>>>>
>>>
>>>I like the concept, but think perhaps the API could be changed a bit.
>>>
>>>Suggest that Plugins can implement a method Plugin::onMessage(String id,
>>>Object data) as suggested, which will be invoked when a message is
>>>"posted".  In addition, Plugins implement (via superclass) a method
>>>Plugin::postMessage(String id, Object data).  Looks like it's currently
>>>called onMessage() and implemented on PluginManager.  Why expose another
>>>class (PluginManager) when we can put this in the Plugin itself?  And
>>>why
>>>call an API that sends a message "onMessage".
>>
>> Agree with this. Keep it to the Plugin interface and name it
>>postMessage.
>>
>>>We should agree on the synchroncity of postMessage() and onMessage()
>>>invocations and document them in the source comments.  Does
>>>postMessage()
>>>not return until all plugins are sent onMessage()?  Or are these
>>>asynchronous?  I think synchronous makes sense, and then we should
>>>document
>>>that onMessage() invocations are blocking the main thread, so shouldn't
>>>do
>>>long-running tasks.
>>
>> Conceptually I think this is no different than making a call into
>>plugins
>> from JS. I would lean towards async mechanics. Some plugins may need to
>>do
>> long-running tasks when handling messages. This kind of reminds me of
>>the
>> discussion we had initially about plugins, whether they are sync/async.
>>We
>> quickly realized that async is the way to go. The project in incubation
>>is
>> called callback, after all ;)
>>
>>>Rather than send every event to every plugin, perhaps plugins should
>>>indicate that they wish to receive events.  Another API perhaps:
>>>Plugin::listenForMessages(boolean).  Don't listen, we won't send
>>>messages.
>>> Not sure it's worth it.
>>
>> +1; set this to false as default and then plugin authors can change +
>> implement onMessage/postMessage when they need it.
>>
>>>
>>>We should consider how the id's should be namespaced.
>>>
>>>We should be documenting for each plugin which id's they send and
>>>respond
>>>to.  Doesn't need to be in the user docs (obviously), but does need to
>>>be
>>>documented somewhere.  I guess code comments will be good enough for
>>>now.
>>
>> Good enough for now, maybe something that should be discussed once we
>>get
>> into plugin packaging.
>>
>>>
>>>In terms of the naming of the APIs themselves, there may be some
>>>confusion
>>>as folks may confuse these names with ones available in the DOM (eg,
>>>https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
>>>suggestion, which I'm not immediately happy with, is to stuff the string
>>>"Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
>>>dunno, maybe not so horrible.
>>
>> A bit more verbose, not a big deal I think. Either way works IMO.
>>
>>>
>>>--
>>>Patrick Mueller
>>>http://muellerware.org
>>
>>


Re: Change to Plugins introduced in Android

Posted by Dave Johnson <da...@gmail.com>.
I like the idea of a messaging API but the first thing that came to my
mind was that we should be using a generic mechanism like web intents
for this.

On Android we have the ability configure a plugin such that the
onOverrideUrlLoading(String url) method is called (handleOpenUrl I
think on iOS) when a URL is loaded that matches (could be regex or
whatever) one that is listed in the plugin configuration xml / plist.

This is also a common way to communicate on most platforms. iOS of
course supports the handling of specific URIs and intents on Android
are pretty much the same thing.

Thoughts?

-dave


On Mon, Nov 21, 2011 at 1:06 PM, Filip Maj <fi...@adobe.com> wrote:
>
>
> On 11-11-16 1:47 PM, "Patrick Mueller" <pm...@gmail.com> wrote:
>
>>On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:
>>
>>> The reason I'm posting this is because we want to keep our plugin
>>> interfaces aligned across platforms. It would be great if the other
>>> platforms implemented this as well. Also would love to hear what the
>>>rest
>>> of the team thinks of this change.
>>>
>>
>>I like the concept, but think perhaps the API could be changed a bit.
>>
>>Suggest that Plugins can implement a method Plugin::onMessage(String id,
>>Object data) as suggested, which will be invoked when a message is
>>"posted".  In addition, Plugins implement (via superclass) a method
>>Plugin::postMessage(String id, Object data).  Looks like it's currently
>>called onMessage() and implemented on PluginManager.  Why expose another
>>class (PluginManager) when we can put this in the Plugin itself?  And why
>>call an API that sends a message "onMessage".
>
> Agree with this. Keep it to the Plugin interface and name it postMessage.
>
>>We should agree on the synchroncity of postMessage() and onMessage()
>>invocations and document them in the source comments.  Does postMessage()
>>not return until all plugins are sent onMessage()?  Or are these
>>asynchronous?  I think synchronous makes sense, and then we should
>>document
>>that onMessage() invocations are blocking the main thread, so shouldn't do
>>long-running tasks.
>
> Conceptually I think this is no different than making a call into plugins
> from JS. I would lean towards async mechanics. Some plugins may need to do
> long-running tasks when handling messages. This kind of reminds me of the
> discussion we had initially about plugins, whether they are sync/async. We
> quickly realized that async is the way to go. The project in incubation is
> called callback, after all ;)
>
>>Rather than send every event to every plugin, perhaps plugins should
>>indicate that they wish to receive events.  Another API perhaps:
>>Plugin::listenForMessages(boolean).  Don't listen, we won't send messages.
>> Not sure it's worth it.
>
> +1; set this to false as default and then plugin authors can change +
> implement onMessage/postMessage when they need it.
>
>>
>>We should consider how the id's should be namespaced.
>>
>>We should be documenting for each plugin which id's they send and respond
>>to.  Doesn't need to be in the user docs (obviously), but does need to be
>>documented somewhere.  I guess code comments will be good enough for now.
>
> Good enough for now, maybe something that should be discussed once we get
> into plugin packaging.
>
>>
>>In terms of the naming of the APIs themselves, there may be some confusion
>>as folks may confuse these names with ones available in the DOM (eg,
>>https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
>>suggestion, which I'm not immediately happy with, is to stuff the string
>>"Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
>>dunno, maybe not so horrible.
>
> A bit more verbose, not a big deal I think. Either way works IMO.
>
>>
>>--
>>Patrick Mueller
>>http://muellerware.org
>
>

Re: Change to Plugins introduced in Android

Posted by Shazron <sh...@gmail.com>.
iOS already has this support since 1.0 - it receives system events and
can register observe any other events that it wants to know about:
https://github.com/callback/callback-ios/blob/master/PhoneGapLib/Classes/PGPlugin.m
(see the init function)

The event names are just constant strings.

On Wed, Nov 16, 2011 at 1:47 PM, Patrick Mueller <pm...@gmail.com> wrote:
> On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:
>
>> The reason I'm posting this is because we want to keep our plugin
>> interfaces aligned across platforms. It would be great if the other
>> platforms implemented this as well. Also would love to hear what the rest
>> of the team thinks of this change.
>>
>
> I like the concept, but think perhaps the API could be changed a bit.
>
> Suggest that Plugins can implement a method Plugin::onMessage(String id,
> Object data) as suggested, which will be invoked when a message is
> "posted".  In addition, Plugins implement (via superclass) a method
> Plugin::postMessage(String id, Object data).  Looks like it's currently
> called onMessage() and implemented on PluginManager.  Why expose another
> class (PluginManager) when we can put this in the Plugin itself?  And why
> call an API that sends a message "onMessage".
>
> We should agree on the synchroncity of postMessage() and onMessage()
> invocations and document them in the source comments.  Does postMessage()
> not return until all plugins are sent onMessage()?  Or are these
> asynchronous?  I think synchronous makes sense, and then we should document
> that onMessage() invocations are blocking the main thread, so shouldn't do
> long-running tasks.
>
> Rather than send every event to every plugin, perhaps plugins should
> indicate that they wish to receive events.  Another API perhaps:
> Plugin::listenForMessages(boolean).  Don't listen, we won't send messages.
>  Not sure it's worth it.
>
> We should consider how the id's should be namespaced.
>
> We should be documenting for each plugin which id's they send and respond
> to.  Doesn't need to be in the user docs (obviously), but does need to be
> documented somewhere.  I guess code comments will be good enough for now.
>
> In terms of the naming of the APIs themselves, there may be some confusion
> as folks may confuse these names with ones available in the DOM (eg,
> https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
> suggestion, which I'm not immediately happy with, is to stuff the string
> "Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
> dunno, maybe not so horrible.
>
> --
> Patrick Mueller
> http://muellerware.org
>

Re: Change to Plugins introduced in Android

Posted by Filip Maj <fi...@adobe.com>.

On 11-11-16 1:47 PM, "Patrick Mueller" <pm...@gmail.com> wrote:

>On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:
>
>> The reason I'm posting this is because we want to keep our plugin
>> interfaces aligned across platforms. It would be great if the other
>> platforms implemented this as well. Also would love to hear what the
>>rest
>> of the team thinks of this change.
>>
>
>I like the concept, but think perhaps the API could be changed a bit.
>
>Suggest that Plugins can implement a method Plugin::onMessage(String id,
>Object data) as suggested, which will be invoked when a message is
>"posted".  In addition, Plugins implement (via superclass) a method
>Plugin::postMessage(String id, Object data).  Looks like it's currently
>called onMessage() and implemented on PluginManager.  Why expose another
>class (PluginManager) when we can put this in the Plugin itself?  And why
>call an API that sends a message "onMessage".

Agree with this. Keep it to the Plugin interface and name it postMessage.

>We should agree on the synchroncity of postMessage() and onMessage()
>invocations and document them in the source comments.  Does postMessage()
>not return until all plugins are sent onMessage()?  Or are these
>asynchronous?  I think synchronous makes sense, and then we should
>document
>that onMessage() invocations are blocking the main thread, so shouldn't do
>long-running tasks.

Conceptually I think this is no different than making a call into plugins
from JS. I would lean towards async mechanics. Some plugins may need to do
long-running tasks when handling messages. This kind of reminds me of the
discussion we had initially about plugins, whether they are sync/async. We
quickly realized that async is the way to go. The project in incubation is
called callback, after all ;)

>Rather than send every event to every plugin, perhaps plugins should
>indicate that they wish to receive events.  Another API perhaps:
>Plugin::listenForMessages(boolean).  Don't listen, we won't send messages.
> Not sure it's worth it.

+1; set this to false as default and then plugin authors can change +
implement onMessage/postMessage when they need it.

>
>We should consider how the id's should be namespaced.
>
>We should be documenting for each plugin which id's they send and respond
>to.  Doesn't need to be in the user docs (obviously), but does need to be
>documented somewhere.  I guess code comments will be good enough for now.

Good enough for now, maybe something that should be discussed once we get
into plugin packaging.

>
>In terms of the naming of the APIs themselves, there may be some confusion
>as folks may confuse these names with ones available in the DOM (eg,
>https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
>suggestion, which I'm not immediately happy with, is to stuff the string
>"Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
>dunno, maybe not so horrible.

A bit more verbose, not a big deal I think. Either way works IMO.

>
>-- 
>Patrick Mueller
>http://muellerware.org


Re: Change to Plugins introduced in Android

Posted by Patrick Mueller <pm...@gmail.com>.
On Thu, Nov 10, 2011 at 12:30, Filip Maj <fi...@adobe.com> wrote:

> The reason I'm posting this is because we want to keep our plugin
> interfaces aligned across platforms. It would be great if the other
> platforms implemented this as well. Also would love to hear what the rest
> of the team thinks of this change.
>

I like the concept, but think perhaps the API could be changed a bit.

Suggest that Plugins can implement a method Plugin::onMessage(String id,
Object data) as suggested, which will be invoked when a message is
"posted".  In addition, Plugins implement (via superclass) a method
Plugin::postMessage(String id, Object data).  Looks like it's currently
called onMessage() and implemented on PluginManager.  Why expose another
class (PluginManager) when we can put this in the Plugin itself?  And why
call an API that sends a message "onMessage".

We should agree on the synchroncity of postMessage() and onMessage()
invocations and document them in the source comments.  Does postMessage()
not return until all plugins are sent onMessage()?  Or are these
asynchronous?  I think synchronous makes sense, and then we should document
that onMessage() invocations are blocking the main thread, so shouldn't do
long-running tasks.

Rather than send every event to every plugin, perhaps plugins should
indicate that they wish to receive events.  Another API perhaps:
Plugin::listenForMessages(boolean).  Don't listen, we won't send messages.
 Not sure it's worth it.

We should consider how the id's should be namespaced.

We should be documenting for each plugin which id's they send and respond
to.  Doesn't need to be in the user docs (obviously), but does need to be
documented somewhere.  I guess code comments will be good enough for now.

In terms of the naming of the APIs themselves, there may be some confusion
as folks may confuse these names with ones available in the DOM (eg,
https://developer.mozilla.org/en/DOM/window.postMessage ).  My only
suggestion, which I'm not immediately happy with, is to stuff the string
"Plugin" into the APIs: onPluginMessage() and postPluginMessage().  I
dunno, maybe not so horrible.

-- 
Patrick Mueller
http://muellerware.org