Skip to content

Commit ff832d1

Browse files
committed
Don't assume assemblies exist
1 parent eaf589c commit ff832d1

10 files changed

+143
-13
lines changed

src/Xamarin.Android.Build.Tasks/Mono.Android/ApplicationAttribute.Partial.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ static partial void AddManualMapping ()
6060

6161
public static ApplicationAttribute FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
6262
{
63+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
64+
// tests which check these situations.
65+
if (provider == null) {
66+
return null;
67+
}
68+
6369
CustomAttribute attr = provider.GetCustomAttributes ("Android.App.ApplicationAttribute")
6470
.SingleOrDefault ();
6571
if (attr == null)

src/Xamarin.Android.Build.Tasks/Mono.Android/InstrumentationAttribute.Partial.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,17 @@
1313
namespace Android.App {
1414

1515
partial class InstrumentationAttribute {
16-
17-
ICollection<string>? specified;
16+
17+
ICollection<string> specified;
1818

1919
public static IEnumerable<InstrumentationAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
2020
{
21+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
22+
// tests which check these situations.
23+
if (provider == null) {
24+
yield break;
25+
}
26+
2127
foreach (CustomAttribute attr in provider.GetCustomAttributes ("Android.App.InstrumentationAttribute")) {
2228
InstrumentationAttribute self = new InstrumentationAttribute ();
2329
self.specified = mapping.Load (self, attr, cache);

src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionAttribute.Partial.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616
namespace Android.App {
1717

1818
partial class PermissionAttribute {
19-
20-
ICollection<string>? specified;
19+
20+
ICollection<string> specified;
2121

2222
public static IEnumerable<PermissionAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
2323
{
24+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
25+
// tests which check these situations.
26+
if (provider == null) {
27+
yield break;
28+
}
29+
2430
var attrs = provider.GetCustomAttributes ("Android.App.PermissionAttribute");
2531
foreach (var attr in attrs) {
2632
PermissionAttribute self = new PermissionAttribute ();

src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionGroupAttribute.Partial.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616
namespace Android.App {
1717

1818
partial class PermissionGroupAttribute {
19-
20-
ICollection<string>? specified;
19+
20+
ICollection<string> specified;
2121

2222
public static IEnumerable<PermissionGroupAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
2323
{
24+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
25+
// tests which check these situations.
26+
if (provider == null) {
27+
yield break;
28+
}
29+
2430
var attrs = provider.GetCustomAttributes ("Android.App.PermissionGroupAttribute");
2531
foreach (var attr in attrs) {
2632
PermissionGroupAttribute self = new PermissionGroupAttribute ();

src/Xamarin.Android.Build.Tasks/Mono.Android/PermissionTreeAttribute.Partial.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,17 @@
1616
namespace Android.App {
1717

1818
partial class PermissionTreeAttribute {
19-
20-
ICollection<string>? specified;
19+
20+
ICollection<string> specified;
2121

2222
public static IEnumerable<PermissionTreeAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
2323
{
24+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
25+
// tests which check these situations.
26+
if (provider == null) {
27+
yield break;
28+
}
29+
2430
var attrs = provider.GetCustomAttributes ("Android.App.PermissionTreeAttribute");
2531
foreach (var attr in attrs) {
2632
PermissionTreeAttribute self = new PermissionTreeAttribute ();

src/Xamarin.Android.Build.Tasks/Mono.Android/SupportsGLTextureAttribute.Partial.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,21 @@ internal XElement ToElement (string packageName, TypeDefinitionCache cache)
3131

3232
public static IEnumerable<SupportsGLTextureAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
3333
{
34+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
35+
// tests which check these situations.
36+
if (provider == null) {
37+
yield break;
38+
}
39+
3440
var attrs = provider.GetCustomAttributes ("Android.App.SupportsGLTextureAttribute");
3541
foreach (var attr in attrs) {
3642
if (attr.HasConstructorArguments && attr.ConstructorArguments.Count == 1) {
3743
SupportsGLTextureAttribute self = new SupportsGLTextureAttribute((string)attr.ConstructorArguments[0].Value);
3844
self.specified = mapping.Load (self, attr, cache);
3945
self.specified.Add("Name");
40-
yield return self;
46+
yield return self;
4147
}
4248
}
4349
}
4450
}
4551
}
46-

src/Xamarin.Android.Build.Tasks/Mono.Android/UsesFeatureAttribute.Partial.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,18 @@ internal XElement ToElement (string packageName, TypeDefinitionCache cache)
3737

3838
public static IEnumerable<UsesFeatureAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
3939
{
40+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
41+
// tests which check these situations.
42+
if (provider == null) {
43+
yield break;
44+
}
45+
4046
var attrs = provider.GetCustomAttributes ("Android.App.UsesFeatureAttribute");
4147
foreach (var attr in attrs) {
4248

4349
UsesFeatureAttribute self = new UsesFeatureAttribute ();
4450

45-
if (attr.HasProperties) {
51+
if (attr.HasProperties) {
4652
// handle the case where the user sets additional properties
4753
self.specified = mapping.Load (self, attr, cache);
4854
if (self.specified.Contains("GLESVersion") && self.GLESVersion==0) {
@@ -66,4 +72,3 @@ public static IEnumerable<UsesFeatureAttribute> FromCustomAttributeProvider (ICu
6672
}
6773
}
6874
}
69-

src/Xamarin.Android.Build.Tasks/Mono.Android/UsesPermissionAttribute.Partial.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ partial class UsesPermissionAttribute {
1616

1717
public static IEnumerable<UsesPermissionAttribute> FromCustomAttributeProvider (ICustomAttributeProvider provider, TypeDefinitionCache cache)
1818
{
19+
// `provider` might be null in situations when application configuration is broken, and it surfaces in a number of
20+
// tests which check these situations.
21+
if (provider == null) {
22+
yield break;
23+
}
24+
1925
var attrs = provider.GetCustomAttributes ("Android.App.UsesPermissionAttribute");
2026
foreach (var attr in attrs) {
2127
UsesPermissionAttribute self;

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

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,86 @@ string ValidAssemblerString (string s)
432432
}
433433
}
434434

435-
return !Log.HasLoggedErrors;
435+
bool ShouldIgnoreSplitConfigs ()
436+
{
437+
if (String.IsNullOrEmpty (CustomBundleConfigFile)) {
438+
return false;
439+
}
440+
441+
return BundleConfigSplitConfigsChecker.ShouldIgnoreSplitConfigs (Log, CustomBundleConfigFile);
442+
}
443+
444+
void GetRequiredTokens (string assemblyFilePath, out int android_runtime_jnienv_class_token, out int jnienv_initialize_method_token, out int jnienv_registerjninatives_method_token)
445+
{
446+
if (File.Exists (assemblyFilePath)) {
447+
using var pe = new PEReader (File.OpenRead (assemblyFilePath));
448+
GetRequiredTokens (pe.GetMetadataReader (), out android_runtime_jnienv_class_token, out jnienv_initialize_method_token, out jnienv_registerjninatives_method_token);
449+
} else {
450+
android_runtime_jnienv_class_token = -1;
451+
jnienv_initialize_method_token = -1;
452+
jnienv_registerjninatives_method_token = -1;
453+
Log.LogDebugMessage ($"Assembly '{assemblyFilePath}' does not exist, unable to read required tokens from it");
454+
return;
455+
}
456+
457+
if (android_runtime_jnienv_class_token == -1 || jnienv_initialize_method_token == -1 || jnienv_registerjninatives_method_token == -1) {
458+
throw new InvalidOperationException ($"Unable to find the required Android.Runtime.JNIEnvInit method tokens for {assemblyFilePath}");
459+
}
460+
}
461+
462+
void GetRequiredTokens (MetadataReader reader, out int android_runtime_jnienv_class_token, out int jnienv_initialize_method_token, out int jnienv_registerjninatives_method_token)
463+
{
464+
android_runtime_jnienv_class_token = -1;
465+
jnienv_initialize_method_token = -1;
466+
jnienv_registerjninatives_method_token = -1;
467+
468+
TypeDefinition? typeDefinition = null;
469+
470+
foreach (TypeDefinitionHandle typeHandle in reader.TypeDefinitions) {
471+
TypeDefinition td = reader.GetTypeDefinition (typeHandle);
472+
if (!TypeMatches (td)) {
473+
continue;
474+
}
475+
476+
typeDefinition = td;
477+
android_runtime_jnienv_class_token = MetadataTokens.GetToken (reader, typeHandle);
478+
break;
479+
}
480+
481+
if (typeDefinition == null) {
482+
return;
483+
}
484+
485+
foreach (MethodDefinitionHandle methodHandle in typeDefinition.Value.GetMethods ()) {
486+
MethodDefinition md = reader.GetMethodDefinition (methodHandle);
487+
string name = reader.GetString (md.Name);
488+
489+
if (jnienv_initialize_method_token == -1 && String.Compare (name, "Initialize", StringComparison.Ordinal) == 0) {
490+
jnienv_initialize_method_token = MetadataTokens.GetToken (reader, methodHandle);
491+
} else if (jnienv_registerjninatives_method_token == -1 && String.Compare (name, "RegisterJniNatives", StringComparison.Ordinal) == 0) {
492+
jnienv_registerjninatives_method_token = MetadataTokens.GetToken (reader, methodHandle);
493+
}
494+
495+
if (jnienv_initialize_method_token != -1 && jnienv_registerjninatives_method_token != -1) {
496+
break;
497+
}
498+
}
499+
500+
501+
bool TypeMatches (TypeDefinition td)
502+
{
503+
string ns = reader.GetString (td.Namespace);
504+
if (String.Compare (ns, "Android.Runtime", StringComparison.Ordinal) != 0) {
505+
return false;
506+
}
507+
508+
string name = reader.GetString (td.Name);
509+
if (String.Compare (name, "JNIEnvInit", StringComparison.Ordinal) != 0) {
510+
return false;
511+
}
512+
513+
return true;
514+
}
515+
}
436516
}
437517
}

src/Xamarin.Android.Build.Tasks/Utilities/ManifestDocument.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,10 @@ XElement CreateApplicationElement (XElement manifest, string applicationClass, L
581581
List<UsesConfigurationAttribute> usesConfigurationAttr = [];
582582
foreach (var assemblyPath in Assemblies) {
583583
var assembly = Resolver.GetAssembly (assemblyPath);
584+
if (assembly == null) {
585+
continue;
586+
}
587+
584588
if (ApplicationAttribute.FromCustomAttributeProvider (assembly, cache) is ApplicationAttribute a) {
585589
assemblyAttr.Add (a);
586590
}

0 commit comments

Comments
 (0)