Skip to content

Commit 1cee050

Browse files
Fix R8 JNI incremental validation tests
Allow blank records when validating generated reachability manifests, and resolve the final AAPT rules through their explicit configuration provenance instead of filesystem name uniqueness. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 9ffb488 commit 1cee050

3 files changed

Lines changed: 29 additions & 6 deletions

File tree

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
400400
BeforeTargets="_CompileToDalvik">
401401
<WriteLinesToFile
402402
File="$(_AndroidR8JniSeedDirectory)final-configuration-items.txt"
403-
Lines="@(_ProguardConfiguration->'%(Filename)%(Extension)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
403+
Lines="@(_ProguardConfiguration->'%(Identity)|%(AndroidSdkBaselineProguardConfiguration)|%(AndroidGeneratedProguardConfiguration)|%(AndroidAaptProguardConfiguration)|%(AndroidR8JniMappedProguardConfiguration)')"
404404
Overwrite="true"
405405
WriteOnlyWhenDifferent="true" />
406406
</Target>
@@ -421,10 +421,16 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
421421
var seedConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "configuration-items.txt"));
422422
var seedConfigurationPaths = seedConfigurationItems.Select (item => item.Split ('|') [0]).ToArray ();
423423
var finalConfigurationItems = File.ReadAllLines (FindSingleFile (projectDirectory, "final-configuration-items.txt"));
424+
var finalAaptConfiguration = finalConfigurationItems
425+
.Select (item => item.Split ('|'))
426+
.Single (metadata => metadata.Length == 5 && metadata [2] == "true" && metadata [3] == "true");
424427
var manifestRules = FindSingleFile (projectDirectory, "manifest_rules.txt");
425-
var finalAaptRules = FindSingleFile (projectDirectory, "aapt_rules.txt", path => !path.Contains ("r8-jni-seed", StringComparison.Ordinal));
428+
var finalAaptRules = Path.IsPathRooted (finalAaptConfiguration [0])
429+
? finalAaptConfiguration [0]
430+
: Path.Combine (projectDirectory, finalAaptConfiguration [0]);
426431
var mappedProjectRules = FindSingleFile (projectDirectory, "proguard_project_references.cfg");
427432
var primaryRules = FindSingleFile (projectDirectory, "proguard_project_primary.cfg");
433+
FileAssert.Exists (finalAaptRules, "The final configured AAPT rules should exist.");
428434
AssertR8MappingRenamesClass (seedMapping, libraryJavaName);
429435
AssertR8MappingRenamesClass (finalMapping, libraryJavaName);
430436
AssertR8MappingContainsMember (finalMapping, libraryJavaName, "nctor_0");
@@ -439,16 +445,18 @@ public R8JniLayoutView (android.content.Context context, android.util.AttributeS
439445
"Seed manifest rules must not include resource custom views.");
440446
StringAssert.Contains ("-keep class com.example.R8JniLayoutView", File.ReadAllText (finalAaptRules),
441447
"Final AAPT rules should retain resource custom-view rules.");
448+
StringAssert.Contains ("#Auto Generated file", File.ReadAllText (finalAaptRules),
449+
"The final configured AAPT file should wrap the generated manifest and resource rules.");
442450
Assert.IsFalse (seedConfigurationPaths.Any (path =>
443451
new [] { "proguard-android.txt", "proguard_xamarin.cfg", "proguard_project_references.cfg", "proguard_project_primary.cfg", "generated-acw-keep.cfg" }.Contains (Path.GetFileName (path), StringComparer.Ordinal)),
444452
"Seed R8 should not receive generated or baseline configurations that pin managed peers.");
445-
Assert.That (finalConfigurationItems, Does.Contain ("proguard-android.txt|true|||"),
453+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard-android.txt|true|||"),
446454
"Final R8 should identify only the SDK baseline by explicit provenance metadata.");
447-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("generated-acw-keep.cfg||true||"),
455+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("generated-acw-keep.cfg||true||"),
448456
"Generated ACW keep rules should carry semantic provenance so R8 can exclude them.");
449-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("aapt_rules.txt||true|true|"),
457+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("aapt_rules.txt||true|true|"),
450458
"Final AAPT rules should carry specific provenance so R8 retains them.");
451-
Assert.That (finalConfigurationItems, Has.Some.EqualTo ("proguard_project_references.cfg||true||true"),
459+
Assert.That (finalConfigurationItems, Has.Some.EndsWith ("proguard_project_references.cfg||true||true"),
452460
"Mapped linked-assembly rules should carry specific provenance so R8 retains them.");
453461
StringAssert.Contains ($"-keep,allowobfuscation class {libraryJavaName.Replace ('/', '.')}", File.ReadAllText (mappedProjectRules));
454462
StringAssert.Contains ("-keepclassmembers,allowobfuscation", File.ReadAllText (mappedProjectRules));

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/JniRemapping/R8MappingTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,18 @@ void kept() -> a
431431
}));
432432
}
433433

434+
[Test]
435+
public void ReachabilityManifestIgnoresEmptyLines ()
436+
{
437+
R8Mapping seed = R8Mapping.Parse (new StringReader ("acme.orig.MyView -> a.b.C:\n"));
438+
R8Mapping final = R8Mapping.Parse (new StringReader ("acme.orig.MyView -> a.b.C:\n"));
439+
440+
CollectionAssert.IsEmpty (seed.GetReachabilityConflicts (final, new [] {
441+
"C\tacme/orig/MyView",
442+
"",
443+
}));
444+
}
445+
434446
[TestCase ("F\tacme/orig/MyView\tcount")]
435447
[TestCase ("M\tacme/orig/MyView\tonClick():void")]
436448
public void MemberOnlyManifestReportsRemovedDeclaringClass (string requiredEntry)

src/Xamarin.Android.Build.Tasks/Utilities/JniRemapping/R8Mapping.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,9 @@ public IEnumerable<string> GetReachabilityConflicts (R8Mapping finalMapping, IEn
404404
{
405405
var reportedRemovedClasses = new HashSet<string> (StringComparer.Ordinal);
406406
foreach (string requiredEntry in requiredEntries) {
407+
if (requiredEntry.Length == 0) {
408+
continue;
409+
}
407410
string [] parts = requiredEntry.Split ('\t');
408411
switch (parts.Length > 0 ? parts [0] : "") {
409412
case "C" when parts.Length == 2:

0 commit comments

Comments
 (0)