Bug 33514 - IntentFilterAttribute does not allow specifying the equivalent of multiple "data" attributes
Summary: IntentFilterAttribute does not allow specifying the equivalent of multiple "d...
Status: VERIFIED FIXED
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries (show other bugs)
Version: unspecified
Hardware: PC Windows
: High enhancement
Target Milestone: C6SR1
Assignee: Atsushi Eno
URL:
Depends on:
Blocks:
 
Reported: 2015-08-31 12:32 UTC by Dimitar Dobrev
Modified: 2015-11-23 12:34 UTC (History)
3 users (show)

See Also:
Tags:
Is this bug a regression?: ---
Last known good build:


Attachments

Description Dimitar Dobrev 2015-08-31 12:32:31 UTC
The Android documentation clearly states that a single intent filter can have multiple "data" (http://developer.android.com/guide/topics/manifest/data-element.html). However, IntentFilterAttribute.Data* properties are all strings, not lists of strings. This makes it extremely inconvenient to use IntentFilterAttribute to handle multiple schemes (http(s)) and multiple paths because a separate IntentFilterAttribute has to be used for each combination. This means that if one needs to handle 2 schemes, 2 URL-s and 5 paths, he would need 2 x 2 x 5 = 20 (!!!) attributes.
I am aware that in such cases Android.manifest can be directly used. However, that doesn't always work because one might need to use different filters per build config (using #ifdef). I am also aware that you cannot create a Data struct (with a DataScheme, DataHost, etc string properties) and use a list of Data in IntentFilterAttribute since properties of attributed are resolved at compilation time. However, you can change the Data* properties to Data*s list properties and use them to construct <data /> elements in the manifest, the same way you do with actions and categories.
Comment 1 Jonathan Pryor 2015-09-01 14:13:27 UTC
This might be one of those instances where it's better to just let you manually write XML in Properties\AndroidManifest.xml and rely on the default "content merge" behavior:

http://developer.xamarin.com/guides/android/advanced_topics/working_with_androidmanifest.xml/+

The fundamental problem is that the types that a custom attribute can contain are limited:

https://msdn.microsoft.com/en-us/library/aa664615(v=vs.71).aspx

Furthermore, since <activity/>/etc. can have multiple <intent-filter/> descriptions, I don't think that's it's really feasible to split out the <data/> element into a separate custom attribute, because order of custom attributes is not necessarily preserved (at least I know of nothing requiring that custom attribute application order be preserved in C# or any other language), meaning something like this:

    [IntentFilter (IntentFilter1...)]
    [Data (Data1...)]
    [IntentFilter (IntentFilter2)]
    [Data (Data2...)]
    public partial class MyActivity : Activity {}

may not be able to reliably match Data1 to the IntentFilter1, and Data2 to IntentFilter2...

If it's not reliable, consistent, or understandable, it's not happening. :-)

It's complicated, and in the absence of a better way to do it (and an array of structs would be SO HANDY for this...), the sanest solution I can think of is the already existing "use Properties\AndroidManifest.xml".
Comment 2 Dimitar Dobrev 2015-09-01 14:24:18 UTC
This wasn't my suggestion at all. I suggested changing IntentFilterAttribute.Data* from strings to lists of strings. This way we will be able to write:

[IntentFilter(DataHosts = new [] { "URL1", "URL2", ... }, DataPaths = new [] { "Path 1", ... } )]

that is, what I said earlier - the same as IntentFilterAttribute.Categories and IntentFilterAttribute.Actions.
Comment 3 Jonathan Pryor 2015-09-01 14:30:16 UTC
> I suggested changing IntentFilterAttribute.Data* from strings to lists of strings

And what happens when the arrays have separate lengths?

    [IntentFilter (
        DataHosts=new[]{"url1"},
        DataPaths=new[]{"path1", "path2"},
        DataPathPrefixes=new[]{"prefix1", "prefix2", "prefix3"}
        ...
    ]

What <data/> elements should the above generate? Should "same indexes" be used?

Though trying to infer whether indexes match each other might be moot; from the docs:

> So, for example, the following filter specification,...
> is equivalent to this one:

Which suggests that the above [IntentFilter] could emit:

    <data android:host="url1" />
    <data android:path="path1" />
    <data android:path="path2" />
    <data android:prefix="prefix1" />
    <data android:prefix="prefix2" />
    <data android:prefix="prefix3" />

and have no relation between anything at all.

The docs certainly imply that the above should work...
Comment 4 Dimitar Dobrev 2015-09-01 14:31:39 UTC
Exactly.
Comment 5 Atsushi Eno 2015-09-16 09:30:59 UTC
Dimitar, with the latest commit to monodroid, I have added those properties on IntentFilterAttribute as you suggested:

                public string[]   DataHosts       {get; set;}
                public string[]   DataMimeTypes   {get; set;}
                public string[]   DataPaths       {get; set;}
                public string[]   DataPathPatterns{get; set;}
                public string[]   DataPathPrefixes{get; set;}
                public string[]   DataPorts       {get; set;}
                public string[]   DataSchemes     {get; set;}

Thanks for the report and ideas!

[master 5eb7c0a]
Comment 6 Dimitar Dobrev 2015-09-16 09:44:38 UTC
You're welcome, I'm glad I could help. I'd be even more glad if you could comment about https://bugzilla.xamarin.com/show_bug.cgi?id=25245, it's been half a year.
Comment 7 Atsushi Eno 2015-09-16 12:41:08 UTC
(Not really an official update to the bug so I comment here instead; one of our devs wrote the most part of the alternative to the existing Java API parser, but he's been busy and had little time to make it solid for general consumption yet. In fact a few days ago we had discussed that particular stuff and that exact bug,  and decided to investigate that get working enough.
We might be able to make it in the next major release (in our optimistic vision) or the next to next. The next major release is still months away, but we branch way earlier to make the product solid enough.)
Comment 8 Dimitar Dobrev 2015-09-16 12:49:03 UTC
Excellent, I am happy to hear there's been some progress about that issue. Parameter names would be really useful. Thank you.
Comment 9 Abhishek 2015-11-23 11:47:11 UTC
I am able to reproduce this issue. Here is the screencast for the same:
http://www.screencast.com/t/sJ7JG2n1WCQ

To verify this issue I have checked this issue with the latest master build:
mono-android-6.0.99-216_4059261ee02c8339979f555a633c297ada98c8c9. Now new properties on IntentFilterAttribute has been added. Here is the screencast for the same:
http://www.screencast.com/t/j2JRGZklbiRQ.

Hence closing this issue.

Thanks!
Comment 10 Abhishek 2015-11-23 12:34:22 UTC
An Update to the Comment 9.

I have checked this issue with the latest master build on Windows:
Xamarin.VisualStudio_99.0.0.751_c9c91d5787facd9e0aa13c7ee38a5611b774be5f
XamarinStudio-5.11.0.457_a7f371803e977c9e370808aaf3a5e2e73d76934d

Now new properties on IntentFilterAttribute has been added.
Screencast for VS: http://www.screencast.com/t/0WBx5qtXg
Screencast for XS: http://www.screencast.com/t/qfouepcGGl

Thanks!

Note You need to log in before you can comment on or make changes to this bug.