Bug 40983 - AndroidManifest exported entry duplicates
Summary: AndroidManifest exported entry duplicates
Status: RESOLVED UPSTREAM
Alias: None
Product: Android
Classification: Xamarin
Component: Tools and Addins ()
Version: 6.0.0
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: dean.ellis
URL:
Depends on:
Blocks:
 
Reported: 2016-05-10 09:07 UTC by Tomasz Cielecki
Modified: 2016-05-19 10:25 UTC (History)
2 users (show)

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


Attachments
Sample project (13.53 KB, application/x-zip-compressed)
2016-05-10 09:07 UTC, Tomasz Cielecki
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED UPSTREAM

Description Tomasz Cielecki 2016-05-10 09:07:03 UTC
Created attachment 15955 [details]
Sample project

I have a project where I want to use the AndroidAltBeaconLibrary nuget[1][2], which is a binding around Android Beacon Library[3]. After compiling the project inspecting the resulting AndroidManifest.xml in the obj folder I see this:

    <receiver android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
        <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
      </intent-filter>
    </receiver>
    <service android:name="org.altbeacon.beacon.service.BeaconService" android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="beacon" />
    <service android:name="org.altbeacon.beacon.BeaconIntentProcessor" android:enabled="true" android:exported="false" />
    <receiver android:name="org.altbeacon.beacon.startup.StartupBroadcastReceiver">
      <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
        <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
      </intent-filter>
    </receiver>
    <service android:name="org.altbeacon.beacon.service.BeaconService" android:enabled="true" android:exported="false" android:isolatedProcess="false" android:label="beacon" />
    <service android:name="org.altbeacon.beacon.BeaconIntentProcessor" android:enabled="true" android:exported="false" />
  </application>
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />

If you look carefully the two receiver nodes and the service nodes are duplicated.

Looking at the source for these entries in the Android Beacon Library I only find a single manifest containing no duplicates.[4]

I would suspect somewhere in the tooling that something is spitting it out twice.

I have tried this both on latest beta and alpha in Visual Studio 2015, both have the same behavior.


[1]: https://github.com/chrisriesgo/Android-AltBeacon-Library/tree/master/AndroidAltBeaconLibrary
[2]: http://www.nuget.org/packages/AndroidAltBeaconLibrary/
[3]: https://github.com/AltBeacon/android-beacon-library
[4]: https://github.com/AltBeacon/android-beacon-library/blob/master/src/main/AndroidManifest.xml
Comment 1 Jonathan Pryor 2016-05-18 20:26:15 UTC
The problem is the combination of two things:

1. The AndroidManifest.xml merge algorithm:

https://github.com/xamarin/xamarin-android/blob/59ec488/src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs#L342-L359

2. *Two* "library" AndroidManifest.xml files are processed:

>                 GenerateJavaStubs Task
...
>                   MergedManifestDocuments:
>                     obj/Debug/__library_projects__/AndroidAltBeaconLibrary/library_project_imports/AndroidManifest.xml
>                     obj/Debug/__library_projects__/AndroidAltBeaconLibrary/library_project_imports/aapt/AndroidManifest.xml

The issue here is that the two MergedManifestDocuments are *identical*, and each provide e.g. org.altbeacon.beacon.service.BeaconService.

Meanwhile, the merge algorithm in (1) is stupid, and in this case grabs the <application/> children of *all* MergedManifestDocuments and...simply appends them.

The appropriate fix is to correct the AndroidAltBeaconLibrary NuGet package so that only one AndroidManifest.xml file is bundled with the package, not *three*:

> $ find obj/Debug/__library_projects__/AndroidAltBeaconLibrary -name AndroidManifest.xml
> obj/Debug/__library_projects__/AndroidAltBeaconLibrary/library_project_imports/aapt/AndroidManifest.xml
> obj/Debug/__library_projects__/AndroidAltBeaconLibrary/library_project_imports/AndroidManifest.xml
> obj/Debug/__library_projects__/AndroidAltBeaconLibrary/library_project_imports/bin/AndroidManifest.xml

Note that the `bin` entry is ignored by the build system, but the `aapt` variant isn't.
Comment 2 Jonathan Pryor 2016-05-18 20:27:20 UTC
@Dean: Is there something we can do to improve the situation? For example, why are so many AndroidManifest.xml files being bundled into the binding assembly in the first place; is that our fault? Should we ignore `.../aapt/AndroidManifest.xml` files when merging?

In general, are we at least partly sane here?
Comment 3 dean.ellis 2016-05-19 10:25:09 UTC
We can probably ignore the aapt one. Remember those Manifest files generally come from the google zip/archive/jar not the c# code that we have in the nuget (I think) so if that has duplicates (its not the first time) then there isn't much we can do about it. 
That said ignoring the aapt directory (like we do the bin) we should be able to do