Skip to content

Commit 69eabe6

Browse files
committed
[WIP] Include blob in apk and load it on runtime
1 parent ff92920 commit 69eabe6

15 files changed

Lines changed: 103 additions & 7 deletions

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.RuntimeConfig.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ See: https://github.com/dotnet/runtime/blob/b13715b6984889a709ba29ea8a1961db469f
4040

4141
<Target Name="_ParseRuntimeConfigFiles"
4242
AfterTargets="GenerateBuildRuntimeConfigurationFiles"
43+
Condition=" '$(GenerateRuntimeConfigurationFiles)' == 'true' "
4344
Inputs="$(ProjectRuntimeConfigFilePath)"
4445
Outputs="$(_BinaryRuntimeConfigPath)">
4546
<RuntimeConfigParserTask

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ public class BuildApk : AndroidTask
8989

9090
public string CheckedBuild { get; set; }
9191

92+
public string RuntimeConfigBinFilePath { get; set; }
93+
9294
[Required]
9395
public string ProjectFullPath { get; set; }
9496

@@ -190,6 +192,10 @@ void ExecuteWithAbi (string [] supportedAbis, string apkInputPath, string apkOut
190192
}
191193
}
192194

195+
if (!String.IsNullOrEmpty (RuntimeConfigBinFilePath) && File.Exists (RuntimeConfigBinFilePath)) {
196+
AddFileToArchiveIfNewer (apk, RuntimeConfigBinFilePath, $"{AssembliesPath}rc.bin", compressionMethod: UncompressedMethod);
197+
}
198+
193199
int count = 0;
194200
foreach (var file in files) {
195201
var item = Path.Combine (file.archivePath.Replace (Path.DirectorySeparatorChar, '/'));

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public class GeneratePackageManagerJava : AndroidTask
5959
[Required]
6060
public bool InstantRunEnabled { get; set; }
6161

62+
public string RuntimeConfigBinFilePath { get; set; }
6263
public string BoundExceptionType { get; set; }
6364

6465
public string PackageNamingPolicy { get; set; }
@@ -261,6 +262,7 @@ void AddEnvironment ()
261262
throw new InvalidOperationException ($"Unsupported BoundExceptionType value '{BoundExceptionType}'");
262263
}
263264

265+
bool haveRuntimeConfigBlob = !String.IsNullOrEmpty (RuntimeConfigBinFilePath) && File.Exists (RuntimeConfigBinFilePath);
264266
var appConfState = BuildEngine4.GetRegisteredTaskObjectAssemblyLocal<ApplicationConfigTaskState> (ApplicationConfigTaskState.RegisterTaskObjectKey, RegisteredTaskObjectLifetime.Build);
265267
foreach (string abi in SupportedAbis) {
266268
NativeAssemblerTargetProvider asmTargetProvider = GetAssemblyTargetProvider (abi);
@@ -279,6 +281,7 @@ void AddEnvironment ()
279281
BoundExceptionType = boundExceptionType,
280282
InstantRunEnabled = InstantRunEnabled,
281283
JniAddNativeMethodRegistrationAttributePresent = appConfState != null ? appConfState.JniAddNativeMethodRegistrationAttributePresent : false,
284+
HaveRuntimeConfigBlob = haveRuntimeConfigBlob,
282285
};
283286

284287
using (var sw = MemoryStreamPool.Shared.CreateStreamWriter ()) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public void CheckIncludedAssemblies ()
8686
new [] {
8787
"Java.Interop.dll",
8888
"Mono.Android.dll",
89+
"rc.bin",
8990
"System.Private.CoreLib.dll",
9091
"System.Runtime.dll",
9192
"System.Linq.dll",

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/Utilities/EnvironmentHelper.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public sealed class ApplicationConfig
2525
public bool broken_exception_transitions;
2626
public bool instant_run_enabled;
2727
public bool jni_add_native_method_registration_attribute_present;
28+
public bool have_runtime_config_blob;
2829
public byte bound_stream_io_exception_type;
2930
public uint package_naming_policy;
3031
public uint environment_variable_count;
@@ -150,27 +151,32 @@ static ApplicationConfig ReadApplicationConfig (string envFile)
150151
ret.jni_add_native_method_registration_attribute_present = ConvertFieldToBool ("jni_add_native_method_registration_attribute_present", envFile, i, field [1]);
151152
break;
152153

153-
case 7: // bound_stream_io_exception_type: byte / .byte
154+
case 7:
155+
AssertFieldType (envFile, ".byte", field [0], i);
156+
ret.have_runtime_config_blob = ConvertFieldToBool ("have_runtime_config_blob", envFile, i, field [1]);
157+
break;
158+
159+
case 8: // bound_stream_io_exception_type: byte / .byte
154160
AssertFieldType (envFile, ".byte", field [0], i);
155161
ret.bound_stream_io_exception_type = ConvertFieldToByte ("bound_stream_io_exception_type", envFile, i, field [1]);
156162
break;
157163

158-
case 8: // package_naming_policy: uint32_t / .word | .long
164+
case 9: // package_naming_policy: uint32_t / .word | .long
159165
Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile}:{i}': {field [0]}");
160166
ret.package_naming_policy = ConvertFieldToUInt32 ("package_naming_policy", envFile, i, field [1]);
161167
break;
162168

163-
case 9: // environment_variable_count: uint32_t / .word | .long
169+
case 10: // environment_variable_count: uint32_t / .word | .long
164170
Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile}:{i}': {field [0]}");
165171
ret.environment_variable_count = ConvertFieldToUInt32 ("environment_variable_count", envFile, i, field [1]);
166172
break;
167173

168-
case 10: // system_property_count: uint32_t / .word | .long
174+
case 11: // system_property_count: uint32_t / .word | .long
169175
Assert.IsTrue (expectedUInt32Types.Contains (field [0]), $"Unexpected uint32_t field type in '{envFile}:{i}': {field [0]}");
170176
ret.system_property_count = ConvertFieldToUInt32 ("system_property_count", envFile, i, field [1]);
171177
break;
172178

173-
case 11: // android_package_name: string / [pointer type]
179+
case 12: // android_package_name: string / [pointer type]
174180
Assert.IsTrue (expectedPointerTypes.Contains (field [0]), $"Unexpected pointer field type in '{envFile}:{i}': {field [0]}");
175181
pointers.Add (field [1].Trim ());
176182
break;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ public void DotNetBuild (string runtimeIdentifiers, bool isRelease)
412412
"es",
413413
$"{proj.ProjectName}.dll",
414414
$"{proj.ProjectName}.pdb",
415+
$"{proj}.runtimeconfig.json",
415416
$"{proj.ProjectName}.xml",
416417
};
417418
CollectionAssert.AreEqual (expectedFiles, files, $"Expected: {string.Join (";", expectedFiles)}\n Found: {string.Join (";", files)}");
@@ -574,7 +575,7 @@ public abstract class Foo<TVirtualView, TNativeView> : AbstractViewHandler<TVirt
574575
where TNativeView : Android.Views.View
575576
#else
576577
where TNativeView : class
577-
#endif
578+
#endif
578579
{
579580
protected Foo (PropertyMapper mapper) : base(mapper)
580581
{

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class ApplicationConfigNativeAssemblyGenerator : NativeAssemblyGenerator
2222
public global::Android.Runtime.BoundExceptionType BoundExceptionType { get; set; }
2323
public bool InstantRunEnabled { get; set; }
2424
public bool JniAddNativeMethodRegistrationAttributePresent { get; set; }
25+
public bool HaveRuntimeConfigBlob { get; set; }
2526

2627
public PackageNamingPolicy PackageNamingPolicy { get; set; }
2728

@@ -70,6 +71,9 @@ protected override void WriteSymbols (StreamWriter output)
7071
WriteCommentLine (output, "jni_add_native_method_registration_attribute_present");
7172
size += WriteData (output, JniAddNativeMethodRegistrationAttributePresent);
7273

74+
WriteCommentLine (output, "have_runtime_config_blob");
75+
size += WriteData (output, HaveRuntimeConfigBlob);
76+
7377
WriteCommentLine (output, "bound_exception_type");
7478
size += WriteData (output, (byte)BoundExceptionType);
7579

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,7 @@ because xbuild doesn't support framework reference assemblies.
15671567
PackageNamingPolicy="$(AndroidPackageNamingPolicy)"
15681568
BoundExceptionType="$(AndroidBoundExceptionType)"
15691569
InstantRunEnabled="$(_InstantRunEnabled)"
1570+
RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)"
15701571
>
15711572
<Output TaskParameter="BuildId" PropertyName="_XamarinBuildId" />
15721573
</GeneratePackageManagerJava>
@@ -2036,7 +2037,8 @@ because xbuild doesn't support framework reference assemblies.
20362037
UncompressedFileExtensions="$(AndroidStoreUncompressedFileExtensions)"
20372038
ProjectFullPath="$(MSBuildProjectFullPath)"
20382039
IncludeWrapSh="$(AndroidIncludeWrapSh)"
2039-
CheckedBuild="$(_AndroidCheckedBuild)">
2040+
CheckedBuild="$(_AndroidCheckedBuild)"
2041+
RuntimeConfigBinFilePath="$(_BinaryRuntimeConfigPath)">
20402042
<Output TaskParameter="OutputFiles" ItemName="ApkFiles" />
20412043
</BuildApk>
20422044
<BuildBaseAppBundle

src/monodroid/jni/application_dso_stub.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ ApplicationConfig application_config = {
4242
/*.broken_exception_transitions =*/ false,
4343
/*.instant_run_enabled =*/ false,
4444
/*.jni_add_native_method_registration_attribute_present =*/ false,
45+
/*.have_runtime_config_blob =*/ false,
4546
/*.bound_exception_type =*/ 0, // System
4647
/*.package_naming_policy =*/ 0,
4748
/*.environment_variable_count =*/ 0,

src/monodroid/jni/embedded-assemblies-zip.cc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, monodroid_sh
5151
}
5252

5353
dynamic_local_string<SENSIBLE_PATH_MAX> entry_name;
54+
#if defined (NET6)
55+
bool runtime_config_blob_found = false;
56+
#endif // def NET6
5457

5558
// clang-tidy claims we have a leak in the loop:
5659
//
@@ -87,6 +90,16 @@ EmbeddedAssemblies::zip_load_entries (int fd, const char *apk_name, monodroid_sh
8790
if (strncmp (prefix, file_name, prefix_len) != 0)
8891
continue;
8992

93+
#if defined (NET6)
94+
if (application_config.have_runtime_config_blob && !runtime_config_blob_found) {
95+
if (utils.ends_with (file_name, SharedConstants::RUNTIME_CONFIG_BLOB_NAME)) {
96+
runtime_config_blob_found = true;
97+
runtime_config_blob_mmap = md_mmap_apk_file (fd, data_offset, file_size, file_name, apk_name);
98+
continue;
99+
}
100+
}
101+
#endif // def NET6
102+
90103
// assemblies must be 4-byte aligned, or Bad Things happen
91104
if ((data_offset & 0x3) != 0) {
92105
log_fatal (LOG_ASSEMBLY, "Assembly '%s' is located at bad offset %lu within the .apk\n", file_name, data_offset);

0 commit comments

Comments
 (0)