Skip to content

Commit 2c6f5cd

Browse files
dellis1972jonpryor
authored andcommitted
[Xamarin.Android.Build.Tasks] Use Google Manifest Merger. (#3918)
Use the Google Manifest Merger tooling to merge library `AndroidManifest.xml` files into the App's `AndroidManifest.xml`. This should allow developers to override and remove some unwanted permissions which are currently automatically imported from some of the support libraries. Documentation on how to use the new manifest merger tooling is at: https://developer.android.com/studio/build/manifest-merge Because of the limitations in Command line argument lengths under Windows we have to build our own entry point for the manifest merger tool. Our entry point takes a single "response" file as an input, with each argument needs to be on a separate line for example: --main AndroidManifest.xml --libs obj\Debug\lp\0\ji\AndroidManifest.xml:obj\Debug\lp\2\ji\AndroidManifest.xml --out android\AndroidManifest.xml We have to put each argument on its own line because of the way the built in Manifest Merger Argument parser works.
1 parent aa05045 commit 2c6f5cd

File tree

20 files changed

+350
-80
lines changed

20 files changed

+350
-80
lines changed

Configuration.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<XAPlatformToolsVersion>29.0.1</XAPlatformToolsVersion>
104104
<XAIncludeProprietaryBits Condition="'$(XAIncludeProprietaryBits)' == ''">False</XAIncludeProprietaryBits>
105105
<XABundleToolVersion Condition="'$(XABundleToolVersion)' == ''">0.10.2</XABundleToolVersion>
106+
<XAManifestMergerToolVersion Condition="'$(XAManifestMergerToolVersion)' == ''">26.5.0</XAManifestMergerToolVersion>
106107
<PathSeparator>$([System.IO.Path]::PathSeparator)</PathSeparator>
107108
<_TestsAotName Condition=" '$(AotAssemblies)' == 'true' ">-Aot</_TestsAotName>
108109
<_TestsProfiledAotName Condition=" '$(AndroidEnableProfiledAot)' == 'true' ">-Profiled</_TestsProfiledAotName>

Xamarin.Android.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Android.Tools.Andro
101101
EndProject
102102
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "r8", "src\r8\r8.csproj", "{1BAFA0CC-0377-46CE-AB7B-7BB2E7B62F63}"
103103
EndProject
104+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "manifestmerger", "src\manifestmerger\manifestmerger.csproj", "{AF8AC493-40AC-4195-82F6-B08EE4B4E49E}"
105+
EndProject
104106
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "aapt2", "src\aapt2\aapt2.csproj", "{0C31DE30-F9DF-4312-BFFE-DCAD558CCF08}"
105107
EndProject
106108
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bundletool", "src\bundletool\bundletool.csproj", "{A0AEF446-3368-4591-9DE6-BC3B2B33337D}"
@@ -310,6 +312,10 @@ Global
310312
{1BAFA0CC-0377-46CE-AB7B-7BB2E7B62F63}.Debug|AnyCPU.Build.0 = Debug|Any CPU
311313
{1BAFA0CC-0377-46CE-AB7B-7BB2E7B62F63}.Release|AnyCPU.ActiveCfg = Release|Any CPU
312314
{1BAFA0CC-0377-46CE-AB7B-7BB2E7B62F63}.Release|AnyCPU.Build.0 = Release|Any CPU
315+
{AF8AC493-40AC-4195-82F6-B08EE4B4E49E}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
316+
{AF8AC493-40AC-4195-82F6-B08EE4B4E49E}.Debug|AnyCPU.Build.0 = Debug|Any CPU
317+
{AF8AC493-40AC-4195-82F6-B08EE4B4E49E}.Release|AnyCPU.ActiveCfg = Release|Any CPU
318+
{AF8AC493-40AC-4195-82F6-B08EE4B4E49E}.Release|AnyCPU.Build.0 = Release|Any CPU
313319
{0C31DE30-F9DF-4312-BFFE-DCAD558CCF08}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
314320
{0C31DE30-F9DF-4312-BFFE-DCAD558CCF08}.Debug|AnyCPU.Build.0 = Debug|Any CPU
315321
{0C31DE30-F9DF-4312-BFFE-DCAD558CCF08}.Release|AnyCPU.ActiveCfg = Release|Any CPU
@@ -411,6 +417,7 @@ Global
411417
{E34BCFA0-CAA4-412C-AA1C-75DB8D67D157} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
412418
{1E5501E8-49C1-4659-838D-CC9720C5208F} = {CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}
413419
{1BAFA0CC-0377-46CE-AB7B-7BB2E7B62F63} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
420+
{AF8AC493-40AC-4195-82F6-B08EE4B4E49E} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
414421
{0C31DE30-F9DF-4312-BFFE-DCAD558CCF08} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
415422
{A0AEF446-3368-4591-9DE6-BC3B2B33337D} = {04E3E11E-B47D-4599-8AFC-50515A95E715}
416423
{D93CAC27-3893-42A3-99F1-2BCA72E186F4} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}

build-tools/installers/create-installers.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@
186186
<_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.jar" />
187187
<_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime.dex" />
188188
<_MSBuildFiles Include="$(MSBuildSrcDir)\java_runtime_fastdev.dex" />
189+
<_MSBuildFiles Include="$(MSBuildSrcDir)\manifestmerger.jar" />
189190
<_MSBuildFiles Include="$(MSBuildSrcDir)\SgmlReaderDll.dll" />
190191
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Aapt.targets" />
191192
<_MSBuildFiles Include="$(MSBuildSrcDir)\Xamarin.Android.Aapt2.targets" />

src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Designer.targets

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ Copyright (C) 2016 Xamarin. All rights reserved.
7070
ResolvedAssemblies="@(_ResolvedAssemblies)"
7171
ResolvedUserAssemblies="@(_ResolvedUserMonoAndroidAssembliesForDesigner)"
7272
ManifestTemplate="$(_AndroidManifestAbs)"
73-
MergedManifestDocuments="@(ExtractedManifestDocuments)"
7473
Debug="$(AndroidIncludeDebugSymbols)"
7574
NeedsInternet="$(AndroidNeedsInternetPermission)"
7675
AndroidSdkPlatform="$(_AndroidApiLevel)"
@@ -87,6 +86,15 @@ Copyright (C) 2016 Xamarin. All rights reserved.
8786
AcwMapFile="$(_AcwMapFile)"
8887
SupportedAbis="$(_BuildTargetAbis)">
8988
</GenerateJavaStubs>
89+
<ManifestMerger
90+
ToolPath="$(JavaToolPath)"
91+
JavaOptions="$(JavaOptions)"
92+
ManifestMergerJarPath="$(AndroidManifestMergerJarPath)"
93+
AndroidManifest="$(IntermediateOutputPath)android\AndroidManifest.xml"
94+
OutputManifestFile="$(IntermediateOutputPath)android\AndroidManifest.xml"
95+
LibraryManifestFiles="@(ExtractedManifestDocuments)"
96+
ManifestPlaceholders="$(AndroidManifestPlaceholders)"
97+
/>
9098
<ConvertCustomView
9199
Condition="Exists('$(_CustomViewMapFile)')"
92100
CustomViewMapFile="$(_CustomViewMapFile)"

src/Xamarin.Android.Build.Tasks/Tasks/GenerateJavaStubs.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ public class GenerateJavaStubs : AndroidTask
4343
public string [] SupportedAbis { get; set; }
4444

4545
public string ManifestTemplate { get; set; }
46-
public string[] MergedManifestDocuments { get; set; }
4746

4847
public bool Debug { get; set; }
4948
public bool MultiDex { get; set; }
@@ -255,7 +254,7 @@ void Run (DirectoryAssemblyResolver res)
255254
manifest.NeedsInternet = NeedsInternet;
256255
manifest.InstantRunEnabled = InstantRunEnabled;
257256

258-
var additionalProviders = manifest.Merge (all_java_types, ApplicationJavaClass, EmbedAssemblies, BundledWearApplicationName, MergedManifestDocuments);
257+
var additionalProviders = manifest.Merge (all_java_types, ApplicationJavaClass, EmbedAssemblies, BundledWearApplicationName);
259258

260259
using (var stream = new MemoryStream ()) {
261260
manifest.Save (stream);
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Xml.Linq;
7+
using Microsoft.Build.Framework;
8+
using Microsoft.Build.Utilities;
9+
10+
namespace Xamarin.Android.Tasks
11+
{
12+
public class ManifestMerger : JavaToolTask
13+
{
14+
public override string TaskPrefix => "AMM";
15+
16+
public override string DefaultErrorCode => $"{TaskPrefix}0000";
17+
18+
[Required]
19+
public string ManifestMergerJarPath { get; set; }
20+
21+
[Required]
22+
public string AndroidManifest { get; set; }
23+
24+
[Required]
25+
public string OutputManifestFile { get; set; }
26+
27+
public string [] LibraryManifestFiles { get; set; }
28+
29+
public string [] ManifestPlaceholders { get; set; }
30+
31+
string tempFile;
32+
string responseFile;
33+
34+
public override bool Execute ()
35+
{
36+
tempFile = OutputManifestFile + ".tmp";
37+
responseFile = Path.Combine (Path.GetDirectoryName (OutputManifestFile), "manifestmerger.rsp");
38+
try {
39+
bool result = base.Execute ();
40+
if (!result)
41+
return result;
42+
var m = new ManifestDocument (tempFile, Log);
43+
using (var ms = new MemoryStream ()) {
44+
m.Save (ms);
45+
MonoAndroidHelper.CopyIfStreamChanged (ms, OutputManifestFile);
46+
return result;
47+
}
48+
} finally {
49+
if (File.Exists (tempFile))
50+
File.Delete (tempFile);
51+
if (File.Exists (responseFile))
52+
File.Delete (responseFile);
53+
}
54+
}
55+
56+
protected override string GenerateCommandLineCommands ()
57+
{
58+
string cmd = GetCommandLineBuilder ().ToString ();
59+
Log.LogDebugMessage (cmd);
60+
return cmd;
61+
}
62+
63+
protected virtual CommandLineBuilder GetCommandLineBuilder ()
64+
{
65+
var cmd = new CommandLineBuilder ();
66+
67+
if (!string.IsNullOrEmpty (JavaOptions)) {
68+
cmd.AppendSwitch (JavaOptions);
69+
}
70+
cmd.AppendSwitchIfNotNull ("-Xmx", JavaMaximumHeapSize);
71+
cmd.AppendSwitchIfNotNull ("-cp ", $"{ManifestMergerJarPath}");
72+
cmd.AppendSwitch ("com.xamarin.manifestmerger.Main");
73+
StringBuilder sb = new StringBuilder ();
74+
sb.AppendLine ("--main");
75+
sb.AppendLine (AndroidManifest);
76+
if (LibraryManifestFiles != null) {
77+
sb.AppendLine ("--libs");
78+
sb.AppendLine ($"{string.Join ($"{Path.PathSeparator}", LibraryManifestFiles)}");
79+
}
80+
if (ManifestPlaceholders != null) {
81+
foreach (var entry in ManifestPlaceholders.Select (e => e.Split (new char [] { '=' }, 2, StringSplitOptions.None))) {
82+
if (entry.Length == 2) {
83+
sb.AppendLine ("--placeholder");
84+
sb.AppendLine ($"{entry [0]}={entry [1]}");
85+
} else
86+
Log.LogWarning ("Invalid application placeholders (AndroidApplicationPlaceholders) value. Use 'key1=value1;key2=value2, ...' format. The specified value was: " + ManifestPlaceholders);
87+
}
88+
}
89+
sb.AppendLine ("--out");
90+
sb.AppendLine (tempFile);
91+
File.WriteAllText (responseFile, sb.ToString ());
92+
cmd.AppendFileNameIfNotNull (responseFile);
93+
return cmd;
94+
}
95+
96+
protected override void LogEventsFromTextOutput (string singleLine, MessageImportance messageImportance)
97+
{
98+
if (ExitCode != 0)
99+
Log.LogCodedError (DefaultErrorCode, singleLine);
100+
base.LogEventsFromTextOutput (singleLine, messageImportance);
101+
}
102+
}
103+
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,12 @@ public void BindingCheckHiddenFiles ([Values (true, false)] bool useShortFileNam
316316
var proj = new XamarinAndroidApplicationProject ();
317317
proj.OtherBuildItems.Add (new BuildItem ("ProjectReference", "..\\Binding\\UnnamedProject.csproj"));
318318
proj.SetProperty (proj.ActiveConfigurationProperties, "UseShortFileNames", useShortFileNames);
319+
proj.AndroidManifest = $@"<?xml version=""1.0"" encoding=""utf-8""?>
320+
<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=""{proj.PackageName}"">
321+
<uses-sdk />
322+
<application android:label=""{proj.ProjectName}"" tools:replace=""android:label"">
323+
</application>
324+
</manifest>";
319325
using (var b = CreateApkBuilder (Path.Combine (path, "App"))) {
320326
Assert.IsTrue (b.Build (proj), "Build should have succeeded.");
321327
var assemblyMap = b.Output.GetIntermediaryPath (Path.Combine ("lp", "map.cache"));

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
using System.Text;
88
using System.Text.RegularExpressions;
99
using System.Threading.Tasks;
10+
using System.Xml;
1011
using System.Xml.Linq;
12+
using System.Xml.XPath;
1113
using Microsoft.Build.Framework;
1214
using Mono.Cecil;
1315
using NUnit.Framework;
@@ -1718,7 +1720,7 @@ public void CheckLintErrorsAndWarnings ()
17181720
{
17191721
FixLintOnWindows ();
17201722

1721-
string disabledIssues = "StaticFieldLeak,ObsoleteSdkInt,AllowBackup";
1723+
string disabledIssues = "StaticFieldLeak,ObsoleteSdkInt,AllowBackup,ExportedReceiver";
17221724

17231725
var proj = new XamarinAndroidApplicationProject () {
17241726
PackageReferences = {
@@ -2319,11 +2321,14 @@ public void ApplicationIdPlaceholder ()
23192321
{
23202322
var proj = new XamarinAndroidApplicationProject ();
23212323
proj.AndroidManifest = proj.AndroidManifest.Replace ("</application>", "<provider android:name='${applicationId}' android:authorities='example' /></application>");
2322-
var builder = CreateApkBuilder ("temp/ApplicationIdPlaceholder");
2323-
builder.Build (proj);
2324-
var appsrc = File.ReadAllText (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
2325-
Assert.IsTrue (appsrc.Contains ("<provider android:name=\"UnnamedProject.UnnamedProject\""), "placeholder not replaced");
2326-
builder.Dispose ();
2324+
using (var builder = CreateApkBuilder ("temp/ApplicationIdPlaceholder")) {
2325+
builder.Build (proj);
2326+
var manifest = XDocument.Load (Path.Combine (Root, builder.ProjectDirectory, "obj", "Debug", "android", "AndroidManifest.xml"));
2327+
var namespaceResolver = new XmlNamespaceManager (new NameTable ());
2328+
namespaceResolver.AddNamespace ("android", "http://schemas.android.com/apk/res/android");
2329+
var element = manifest.XPathSelectElement ("/manifest/application/provider[@android:name='UnnamedProject.UnnamedProject']", namespaceResolver);
2330+
Assert.IsNotNull (element, "placeholder not replaced");
2331+
}
23272332
}
23282333

23292334
[Test]

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ public void ManifestPlaceholders ()
453453
using (var builder = CreateApkBuilder (Path.Combine ("temp", TestContext.CurrentContext.Test.Name), false, false)) {
454454
builder.Build (proj);
455455
var manifest = builder.Output.GetIntermediaryAsText (Root, Path.Combine ("android", "AndroidManifest.xml"));
456-
Assert.IsTrue (manifest.Contains ("application android:label=\"val1\""), "#1");
456+
Assert.IsTrue (manifest.Contains (" android:label=\"val1\""), "#1");
457457
Assert.IsTrue (manifest.Contains (" x=\"a=b\\c\"".Replace ('\\', Path.DirectorySeparatorChar)), "#2");
458458
}
459459
}
@@ -659,7 +659,7 @@ public class TestActivity2 : FragmentActivity {
659659
[Test]
660660
public void AllActivityAttributeProperties ()
661661
{
662-
const string expectedOutput = "android:allowEmbedded=\"true\" android:allowTaskReparenting=\"true\" android:alwaysRetainTaskState=\"true\" android:autoRemoveFromRecents=\"true\" android:banner=\"@drawable/icon\" android:clearTaskOnLaunch=\"true\" android:colorMode=\"hdr\" android:configChanges=\"mcc\" android:description=\"@string/app_name\" android:directBootAware=\"true\" android:documentLaunchMode=\"never\" android:enabled=\"true\" android:enableVrMode=\"foo\" android:excludeFromRecents=\"true\" android:exported=\"true\" android:finishOnCloseSystemDialogs=\"true\" android:finishOnTaskLaunch=\"true\" android:hardwareAccelerated=\"true\" android:icon=\"@drawable/icon\" android:immersive=\"true\" android:label=\"TestActivity\" android:launchMode=\"singleTop\" android:lockTaskMode=\"normal\" android:logo=\"@drawable/icon\" android:maxAspectRatio=\"1.2\" android:maxRecents=\"1\" android:multiprocess=\"true\" android:name=\"com.contoso.TestActivity\" android:noHistory=\"true\" android:parentActivityName=\"unnamedproject.unnamedproject.MainActivity\" android:permission=\"com.contoso.permission.TEST_ACTIVITY\" android:persistableMode=\"persistNever\" android:process=\"com.contoso.process.testactivity_process\" android:recreateOnConfigChanges=\"mcc\" android:relinquishTaskIdentity=\"true\" android:resizeableActivity=\"true\" android:resumeWhilePausing=\"true\" android:rotationAnimation=\"crossfade\" android:roundIcon=\"@drawable/icon\" android:screenOrientation=\"portrait\" android:showForAllUsers=\"true\" android:showOnLockScreen=\"true\" android:showWhenLocked=\"true\" android:singleUser=\"true\" android:stateNotNeeded=\"true\" android:supportsPictureInPicture=\"true\" android:taskAffinity=\"com.contoso\" android:theme=\"@android:style/Theme.Light\" android:turnScreenOn=\"true\" android:uiOptions=\"splitActionBarWhenNarrow\" android:visibleToInstantApps=\"true\" android:windowSoftInputMode=\"stateUnchanged|adjustUnspecified\"";
662+
const string expectedOutput = "android:name=\"com.contoso.TestActivity\" android:allowEmbedded=\"true\" android:allowTaskReparenting=\"true\" android:alwaysRetainTaskState=\"true\" android:autoRemoveFromRecents=\"true\" android:banner=\"@drawable/icon\" android:clearTaskOnLaunch=\"true\" android:colorMode=\"hdr\" android:configChanges=\"mcc\" android:description=\"@string/app_name\" android:directBootAware=\"true\" android:documentLaunchMode=\"never\" android:enableVrMode=\"foo\" android:enabled=\"true\" android:excludeFromRecents=\"true\" android:exported=\"true\" android:finishOnCloseSystemDialogs=\"true\" android:finishOnTaskLaunch=\"true\" android:hardwareAccelerated=\"true\" android:icon=\"@drawable/icon\" android:immersive=\"true\" android:label=\"TestActivity\" android:launchMode=\"singleTop\" android:lockTaskMode=\"normal\" android:logo=\"@drawable/icon\" android:maxAspectRatio=\"1.2\" android:maxRecents=\"1\" android:multiprocess=\"true\" android:noHistory=\"true\" android:parentActivityName=\"unnamedproject.unnamedproject.MainActivity\" android:permission=\"com.contoso.permission.TEST_ACTIVITY\" android:persistableMode=\"persistNever\" android:process=\"com.contoso.process.testactivity_process\" android:recreateOnConfigChanges=\"mcc\" android:relinquishTaskIdentity=\"true\" android:resizeableActivity=\"true\" android:resumeWhilePausing=\"true\" android:rotationAnimation=\"crossfade\" android:roundIcon=\"@drawable/icon\" android:screenOrientation=\"portrait\" android:showForAllUsers=\"true\" android:showOnLockScreen=\"true\" android:showWhenLocked=\"true\" android:singleUser=\"true\" android:stateNotNeeded=\"true\" android:supportsPictureInPicture=\"true\" android:taskAffinity=\"com.contoso\" android:theme=\"@android:style/Theme.Light\" android:turnScreenOn=\"true\" android:uiOptions=\"splitActionBarWhenNarrow\" android:visibleToInstantApps=\"true\" android:windowSoftInputMode=\"stateUnchanged|adjustUnspecified\"";
663663

664664
var proj = new XamarinAndroidApplicationProject ();
665665

@@ -739,7 +739,7 @@ class TestActivity : Activity { }"
739739
[Test]
740740
public void AllServiceAttributeProperties ()
741741
{
742-
const string expectedOutput = "android:directBootAware=\"true\" android:enabled=\"true\" android:exported=\"true\" android:foregroundServiceType=\"connectedDevice\" android:icon=\"@drawable/icon\" android:isolatedProcess=\"true\" android:label=\"TestActivity\" android:name=\"com.contoso.TestActivity\" android:permission=\"com.contoso.permission.TEST_ACTIVITY\" android:process=\"com.contoso.process.testactivity_process\" android:roundIcon=\"@drawable/icon\"";
742+
const string expectedOutput = "android:name=\"com.contoso.TestActivity\" android:directBootAware=\"true\" android:enabled=\"true\" android:exported=\"true\" android:foregroundServiceType=\"connectedDevice\" android:icon=\"@drawable/icon\" android:isolatedProcess=\"true\" android:label=\"TestActivity\" android:permission=\"com.contoso.permission.TEST_ACTIVITY\" android:process=\"com.contoso.process.testactivity_process\" android:roundIcon=\"@drawable/icon\"";
743743

744744
var proj = new XamarinAndroidApplicationProject ();
745745

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="${PACKAGENAME}">
3-
<uses-sdk />
4-
<application android:label="${PROJECT_NAME}">
5-
</application>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
android:versionCode="1"
5+
android:versionName="1.0"
6+
package="${PACKAGENAME}"
7+
>
8+
<uses-sdk />
9+
<application android:label="${PROJECT_NAME}">
10+
</application>
611
</manifest>

0 commit comments

Comments
 (0)