Re: [Powerbox] Fine-grained and non-installed providers

OK, this is now coming together nicely in my head.

Tweaks:

(1) It should be up to the interface to decide what its specializations
mean.  An interface which represents a file would probably use MIME
types, but other interfaces may choose some other taxonomy for their space,
as long as it is hierarchical.

(2) I think we should consider a trailing "/*" to be redundant.  Otherwise,
it would be impossible to subdivide an existing category without breaking
existing customers who omit the "/*" when requesting that category.

(3) There's often more than one sensible way to categorize an object space.
 For example, files might be categorized by type, or by language.  This may
be a bit of a stretch, but let's say an app wants to accept any file type,
but only if the content is Chinese.  How is this expressed?  Probably like:

  com.example.File/*;lang=cn

I use a semicolon here because that's what the HTTP "Accept" header uses to
delimit such parameters.  I think we should use commas to delimit separate
interfaces which are accepted, again in line with HTTP's "Accept".  So a
hypothetical audio player that wants Chinese-language audio might be:

  com.example.AudioInput;lang=cn,com.example.File/audio/*;lang=cn

(4) Like HTTP's "Accept", we should define a universal parameter called "q"
which can be used to indicate preference for one type over another.  So a
program which prefers Chinese files but will also accept other files might
say:

  com.example.File;lang=cn;q=1,com.example.File;q=0.5

(5) The meaning of all parameters other than "q" are up to the interface to
define.  Parameters are matched using the same rules as the type.  So, a
request for "lang=en" matches "lang=en/us" and "lang=en/uk", or just
"lang=en".  (Note that our standard won't actually say anything about how
languages are specified; this is just an example.)

On Mon, Mar 8, 2010 at 2:56 AM, Mark Seaborn <mseaborn@chromium.org> wrote:

> On Wed, Mar 3, 2010 at 1:47 AM, Kenton Varda <kenton@google.com> wrote:
>
>> On Sun, Feb 28, 2010 at 6:09 AM, Mark Seaborn <mseaborn@chromium.org>wrote:
>>
>>> Ideally the Powerbox's filtering rules should produce the following
>>> outcomes:
>>>
>>>   Requested  || Powerbox displays:
>>>   type       || Sound recorder | Camera | Local file chooser
>>>   -----------||----------------|--------|-------------------
>>>   Audio file || yes            | no     | yes
>>>   Image file || no             | yes    | yes
>>>   Any file   || yes            | yes    | yes
>>>
>>> We don't want the Powerbox to have a hard-coded list of subtype
>>> relationships (e.g. that "image file" is a subtype of "file") and we don't
>>> want the local file chooser to have to list all the file types it could
>>> possibly provide ("image file", "audio file", etc.).
>>>
>>> I think the way to handle this is to encode subtype relationships into
>>> type names.  For example:
>>>  * Local file chooser provides "file/*"
>>>  * Sound recorder provides "file/audio"
>>>  * Camera provides "file/image"
>>> So "file/*" would match "file/image" and vice versa, but "file/image"
>>> would not match "file/audio".  This satisfies the truth table above.
>>>
>>
>> This all sounds very interesting, but it's also getting uncomfortably
>> complicated for a standard.
>>
>
> Actually, the rules I am suggesting are fairly simple and can be
> implemented in just a few lines of Python:
>
> def matches_wildcard(ty, possible_wildcard):
>     return (possible_wildcard.endswith("*") and
>             ty.startswith(possible_wildcard[:-1]))
>
> def types_match(type1, type2):
>     return (type1 == type2 or
>             matches_wildcard(type1, type2) or
>             matches_wildcard(type2, type1))
>
> def typelists_match(typelist1, typelist2):
>     return any(types_match(type1, type2)
>                for type1 in typelist1.split(";")
>                for type2 in typelist2.split(";"))
>
> # Using the short type names above:
>
> print typelists_match("file/audio", "file/*")
> # prints True
>
> print typelists_match("file/audio;file/video", "file/audio")
> # prints True
>
> print typelists_match("printer/postscript", "file/text")
> # prints False
>
>
>
>>  And how does this extend to specific interfaces?  What happens when we
>> replace "file" with "implements the com.example.File interface"?  Audio
>> files don't implement a different interface from regular files, unless you
>> add a decoder adapter on top.
>>
>
> We can just concatenate the Java-style reverse-domain-name interface names
> that you suggest with MIME types.  For example:
>
> print typelists_match("com.example.File/*", "com.example.File/audio/mpeg")
> # prints True
>
> print typelists_match("com.example.Printer", "com.example.File/audio/*")
> # prints False
>
> A generic file chooser provider would offer the type "com.example.File/*",
> while a music player might request the type "com.example.File/audio/mpeg".
>
>
>> It seems like my music player would ask for "An implementation of
>> com.example.AudioOutput OR an implementation of com.example.File with MIME
>> type 'audio/*'".  How is this expressed?  And how does a provider satisfy
>> it?
>>
>
> I think you mean AudioInput not AudioOutput.  The music player could
> request the type list "com.example.AudioInput;com.example.File/audio/*".
> This would match a provider that offers "com.example.AudioInput" or a
> provider that offers "com.example.File/audio/ogg".
>
> print typelists_match(
>     "com.example.File/audio/ogg",
>     "com.example.AudioInputStream;com.example.File/audio/*")
> # prints True
>
> Mark
>
>

Received on Monday, 8 March 2010 20:00:29 UTC