@@ -123,11 +123,60 @@ public void Execute_ParsesTargetFrameworkVersion (string tfv)
123123 Assert . IsTrue ( task . Execute ( ) , $ "Task should succeed with TargetFrameworkVersion='{ tfv } '.") ;
124124 }
125125
126+ [ Test ]
127+ public void Execute_ManifestPlaceholdersAreResolvedForRooting ( )
128+ {
129+ var path = Path . Combine ( "temp" , TestName ) ;
130+ var outputDir = Path . Combine ( Root , path , "typemap" ) ;
131+ var javaDir = Path . Combine ( Root , path , "java" ) ;
132+ var manifestTemplate = Path . Combine ( Root , path , "AndroidManifest.xml" ) ;
133+ var mergedManifest = Path . Combine ( Root , path , "obj" , "android" , "AndroidManifest.xml" ) ;
134+ var applicationRegistration = Path . Combine ( Root , path , "src" , "net" , "dot" , "android" , "ApplicationRegistration.java" ) ;
135+ var warnings = new List < BuildWarningEventArgs > ( ) ;
136+
137+ var monoAndroidItem = FindMonoAndroidDll ( ) ;
138+ if ( monoAndroidItem is null ) {
139+ Assert . Ignore ( "Mono.Android.dll not found; skipping." ) ;
140+ return ;
141+ }
142+
143+ var manifestDirectory = Path . GetDirectoryName ( manifestTemplate ) ;
144+ if ( manifestDirectory is null ) {
145+ Assert . Fail ( "Could not determine manifest template directory." ) ;
146+ }
147+ Directory . CreateDirectory ( manifestDirectory ) ;
148+ File . WriteAllText ( manifestTemplate , """
149+ <?xml version="1.0" encoding="utf-8"?>
150+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="${applicationId}">
151+ <application android:name=".Application" />
152+ <instrumentation android:name=".Instrumentation" />
153+ </manifest>
154+ """ ) ;
155+
156+ var task = CreateTask ( new [ ] { monoAndroidItem } , outputDir , javaDir , warnings : warnings ) ;
157+ task . ManifestTemplate = manifestTemplate ;
158+ task . MergedAndroidManifestOutput = mergedManifest ;
159+ task . ApplicationRegistrationOutputFile = applicationRegistration ;
160+ task . PackageName = "android.app" ;
161+ task . AndroidApiLevel = "35" ;
162+ task . SupportedOSPlatformVersion = "21" ;
163+ task . RuntimeProviderJavaName = "mono.MonoRuntimeProvider" ;
164+ task . ManifestPlaceholders = "applicationId=android.app" ;
165+
166+ Assert . IsTrue ( task . Execute ( ) , "Task should succeed." ) ;
167+ FileAssert . Exists ( applicationRegistration ) ;
168+
169+ var registrationText = File . ReadAllText ( applicationRegistration ) ;
170+ StringAssert . Contains ( "mono.android.Runtime.registerNatives (android.app.Application.class);" , registrationText ) ;
171+ StringAssert . Contains ( "mono.android.Runtime.registerNatives (android.app.Instrumentation.class);" , registrationText ) ;
172+ Assert . IsFalse ( warnings . Any ( w => w . Code == "XA4250" ) , "Resolved placeholder-based manifest references should not log XA4250." ) ;
173+ }
174+
126175 GenerateTrimmableTypeMap CreateTask ( ITaskItem [ ] assemblies , string outputDir , string javaDir ,
127- IList < BuildMessageEventArgs > ? messages = null , string tfv = "v11.0" )
176+ IList < BuildMessageEventArgs > ? messages = null , IList < BuildWarningEventArgs > ? warnings = null , string tfv = "v11.0" )
128177 {
129178 return new GenerateTrimmableTypeMap {
130- BuildEngine = new MockBuildEngine ( TestContext . Out , messages : messages ) ,
179+ BuildEngine = new MockBuildEngine ( TestContext . Out , warnings : warnings , messages : messages ) ,
131180 ResolvedAssemblies = assemblies ,
132181 OutputDirectory = outputDir ,
133182 JavaSourceOutputDirectory = javaDir ,
0 commit comments