Skip to content

Commit d794534

Browse files
authored
[Xamarin.Android.Build.Tasks] Add Support for AndroidManifest.xml overlays (#5325)
Fixes #5312 The manifest merger tool supports providing additional AndroidManifest.xml files which will `overlay` on top of the final file. This commit adds a new Build Action `AndroidManifestOverlay` which can be used to provide these files to the manifest merger. Users can now use these overlay files to alter the manifest during build time. This can be for adding new permissions or even removing ones that are not needed. It will also allow for different manifest files to be generated for debug/release configurations. This can be done by conditionally including `overlay` files depending on the `$(Configuration)`. ``` <ItemGroup> <AndroidManifestOverlay Include="DebugPermissions.xml" Condition=" '$(Configuration)' == 'Debug' " /> </ItemGroup> ```
1 parent a3d4d19 commit d794534

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

Documentation/guides/building-apps/build-items.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,36 @@ which tests to enable and disable.
8686
See the [lint documentation](https://developer.android.com/studio/write/lint)
8787
for more details.
8888

89+
## AndroidManifestOverlay
90+
91+
The build action `AndroidManifestOverlay` can be used to provide additional
92+
`AndroidManifest.xml` files to the [Manifest Merger]([~/android/deploy-test/building-apps/build-properties.md#](https://developer.android.com/studio/build/manifest-merge)) tool.
93+
Files with this build action will be passed to the Manifest Merger along with
94+
the main `AndroidManifest.xml` file and any additional manifest files from
95+
references. These will then be merged into the final manifest.
96+
97+
You can use this build action to provide additional changes and settings to
98+
your app depending on your build configuration. For example if you need to
99+
have a specific permission only while debugging, you can use the overlay to
100+
inject that permission when debugging. For example given the following
101+
overlay file contents
102+
103+
```
104+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
105+
<uses-permission android:name="android.permission.CAMERA" />
106+
</manifest>
107+
```
108+
109+
you can use the following to add this for a debug build.
110+
111+
```
112+
<ItemGroup>
113+
<AndroidManifestOverlay Include="DebugPermissions.xml" Condition=" '$(Configuration)' == 'Debug' " />
114+
</ItemGroup>
115+
```
116+
117+
Introduced in Xamarin.Android 11.2
118+
89119
## AndroidNativeLibrary
90120

91121
[Native libraries](~/android/platform/native-libraries.md)

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/ManifestTest.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,33 @@ public void CheckElementReOrdering ([Values (true, false)] bool useAapt2)
150150
}
151151
}
152152

153+
[Test]
154+
public void OverlayManifestTest ()
155+
{
156+
var proj = new XamarinAndroidApplicationProject () {
157+
IsRelease = true,
158+
ManifestMerger = "manifestmerger.jar",
159+
};
160+
proj.AndroidManifest = @"<?xml version=""1.0"" encoding=""utf-8""?>
161+
<manifest xmlns:android=""http://schemas.android.com/apk/res/android"" xmlns:tools=""http://schemas.android.com/tools"" android:versionCode=""1"" android:versionName=""1.0"" package=""foo.foo"">
162+
<application android:label=""foo"">
163+
</application>
164+
</manifest>";
165+
proj.OtherBuildItems.Add (new BuildItem ("AndroidManifestOverlay", "ManifestOverlay.xml") {
166+
TextContent = () => @"<?xml version=""1.0"" encoding=""utf-8""?>
167+
<manifest xmlns:android=""http://schemas.android.com/apk/res/android"">
168+
<uses-permission android:name=""android.permission.CAMERA"" />
169+
</manifest>
170+
"
171+
});
172+
using (var b = CreateApkBuilder ("temp/OverlayManifestTest", cleanupAfterSuccessfulBuild: true, cleanupOnDispose: false)) {
173+
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
174+
var manifestFile = Path.Combine (Root, b.ProjectDirectory, proj.IntermediateOutputPath, "android", "AndroidManifest.xml");
175+
var text = File.ReadAllText (manifestFile);
176+
StringAssert.Contains ("android.permission.CAMERA", text, $"{manifestFile} should contain 'android.permission.CAMERA'");
177+
}
178+
}
179+
153180
[Test]
154181
public void RemovePermissionTest ()
155182
{

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ Copyright (C) 2011-2012 Xamarin. All rights reserved.
171171
<AvailableItemName Include="MultiDexMainDexList" />
172172
<AvailableItemName Include="ProguardConfiguration" />
173173
<AvailableItemName Include="ProjectReference" />
174+
<AvailableItemName Include="AndroidManifestOverlay" />
174175
</ItemGroup>
175176

176177
<!-- Version/fx properties -->
@@ -1442,6 +1443,7 @@ because xbuild doesn't support framework reference assemblies.
14421443
OutputManifestFile="$(IntermediateOutputPath)android\AndroidManifest.xml"
14431444
LibraryManifestFiles="@(ExtractedManifestDocuments)"
14441445
ManifestPlaceholders="$(AndroidManifestPlaceholders)"
1446+
ManifestOverlayFiles="@(AndroidManifestOverlay)"
14451447
/>
14461448
<ItemGroup>
14471449
<FileWrites Include="$(IntermediateOutputPath)android\AndroidManifest.xml" />

0 commit comments

Comments
 (0)