Skip to content

Commit 1ea37be

Browse files
committed
Make AndroidSampleApp use host_runtime_contact::external_assembly_probe
1 parent 57974b0 commit 1ea37be

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

src/mono/sample/Android/AndroidSampleApp.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
<ItemGroup>
2121
<RuntimeComponents Condition="'$(RuntimeFlavor)' == 'Mono' and '$(DiagnosticPorts)' != ''" Include="diagnostics_tracing" />
22+
<RuntimeHeaders Include="$(SharedNativeRoot)" Condition="'$(RuntimeFlavor)' != 'Mono'"/>
2223
</ItemGroup>
2324

2425
<Import Project="$(MonoProjectRoot)\msbuild\android\build\AndroidBuild.props" />

src/tasks/AndroidAppBuilder/Templates/monodroid-coreclr.c

+83-17
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <coreclrhost.h>
1717
#include <dirent.h>
1818

19+
#include <corehost/host_runtime_contract.h>
20+
1921
/********* exported symbols *********/
2022

2123
/* JNI exports */
@@ -34,11 +36,15 @@ Java_net_dot_MonoRunner_freeNativeResources (JNIEnv* env, jobject thiz);
3436

3537
/********* implementation *********/
3638

37-
static const char* g_bundle_path = NULL;
39+
static char* g_bundle_path = NULL;
3840
static const char* g_executable_path = NULL;
3941
static unsigned int g_coreclr_domainId = 0;
4042
static void* g_coreclr_handle = NULL;
4143

44+
#define MAX_MAPPED_COUNT 50 // Arbitrarily 'large enough' number
45+
static void* g_mapped_files[MAX_MAPPED_COUNT];
46+
static size_t g_mapped_file_sizes[MAX_MAPPED_COUNT];
47+
static unsigned int g_mapped_files_count = 0;
4248

4349
#define LOG_INFO(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, "DOTNET", fmt, ##__VA_ARGS__)
4450
#define LOG_ERROR(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, "DOTNET", fmt, ##__VA_ARGS__)
@@ -70,7 +76,7 @@ strncpy_str (JNIEnv *env, char *buff, jstring str, int nbuff)
7076

7177
/*
7278
* Get the list of trusted assemblies from a specified @dir_path.
73-
* The path is searched for .dll files which when found are concatenated
79+
* The path is searched for .dll files which when found are concatenated
7480
* to the output string @tpas separated by ':'.
7581
* The output string should be freed by the caller.
7682
* The return value is the length of the output string.
@@ -147,6 +153,56 @@ bundle_executable_path (const char* executable, const char* bundle_path, const c
147153
return executable_path_len;
148154
}
149155

156+
static bool
157+
external_assembly_probe(const char* name, void** data, int64_t* size)
158+
{
159+
if (g_mapped_files_count >= MAX_MAPPED_COUNT)
160+
{
161+
LOG_ERROR("Too many mapped files, cannot map %s", name);
162+
return false;
163+
}
164+
165+
// Get just the file name
166+
const char* pos = strrchr(name, '/');
167+
if (pos != NULL)
168+
name = pos + 1;
169+
170+
// Look in the bundle path where the files were extracted
171+
char full_path[1024];
172+
size_t path_len = strlen(g_bundle_path) + strlen(name) + 1; // +1 for '/'
173+
size_t res = snprintf(full_path, path_len + 1, "%s/%s", g_bundle_path, name);
174+
if (res < 0 || res != path_len)
175+
return false;
176+
177+
int fd = open(full_path, O_RDONLY);
178+
if (fd == -1)
179+
return false;
180+
181+
struct stat buf;
182+
if (fstat(fd, &buf) == -1)
183+
{
184+
close(fd);
185+
return false;
186+
}
187+
188+
int64_t size_local = buf.st_size;
189+
void* mapped = mmap(NULL, size_local, PROT_READ, MAP_PRIVATE, fd, 0);
190+
if (mapped == MAP_FAILED)
191+
{
192+
close(fd);
193+
return false;
194+
}
195+
196+
LOG_INFO("Mapped %s -> %s", name, full_path);
197+
g_mapped_files[g_mapped_files_count] = mapped;
198+
g_mapped_file_sizes[g_mapped_files_count] = size_local;
199+
g_mapped_files_count++;
200+
close(fd);
201+
*data = mapped;
202+
*size = size_local;
203+
return true;
204+
}
205+
150206
static void
151207
free_resources ()
152208
{
@@ -166,9 +222,13 @@ free_resources ()
166222
coreclr_shutdown (g_coreclr_handle, g_coreclr_domainId);
167223
g_coreclr_handle = NULL;
168224
}
225+
for (int i = 0; i < g_mapped_files_count; ++i)
226+
{
227+
munmap (g_mapped_files[i], g_mapped_file_sizes[i]);
228+
}
169229
}
170230

171-
static int
231+
static int
172232
mono_droid_execute_assembly (const char* executable_path, void* coreclr_handle, unsigned int coreclr_domainId, int managed_argc, const char** managed_argv)
173233
{
174234
unsigned int rv;
@@ -178,6 +238,8 @@ mono_droid_execute_assembly (const char* executable_path, void* coreclr_handle,
178238
return rv;
179239
}
180240

241+
#define PROPERTY_COUNT 3
242+
181243
static int
182244
mono_droid_runtime_init (const char* executable)
183245
{
@@ -198,34 +260,38 @@ mono_droid_runtime_init (const char* executable)
198260

199261
chdir (g_bundle_path);
200262

201-
// TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
263+
struct host_runtime_contract host_contract = {
264+
sizeof(struct host_runtime_contract),
265+
NULL, // context
266+
NULL, // get_runtime_property
267+
NULL, // bundle_proble
268+
NULL, // pinvoke_override
269+
&external_assembly_probe };
202270

203-
const char* appctx_keys[3];
271+
const char* appctx_keys[PROPERTY_COUNT];
204272
appctx_keys[0] = "RUNTIME_IDENTIFIER";
205273
appctx_keys[1] = "APP_CONTEXT_BASE_DIRECTORY";
206-
appctx_keys[2] = "TRUSTED_PLATFORM_ASSEMBLIES";
274+
appctx_keys[2] = "HOST_RUNTIME_CONTRACT";
207275

208-
const char* appctx_values[3];
276+
const char* appctx_values[PROPERTY_COUNT];
209277
appctx_values[0] = ANDROID_RUNTIME_IDENTIFIER;
210278
appctx_values[1] = g_bundle_path;
211-
size_t tpas_len = get_tpas_from_path(g_bundle_path, &appctx_values[2]);
212-
if (tpas_len < 1)
213-
{
214-
LOG_ERROR("Failed to get trusted assemblies from path: %s", g_bundle_path);
215-
return -1;
216-
}
279+
280+
char contract_str[19]; // 0x + 16 hex digits + '\0'
281+
snprintf(contract_str, 19, "0x%zx", (size_t)(&host_contract));
282+
appctx_values[2] = contract_str;
217283

218284
LOG_INFO ("Calling coreclr_initialize");
219285
int rv = coreclr_initialize (
220286
g_executable_path,
221287
executable,
222-
3,
288+
PROPERTY_COUNT,
223289
appctx_keys,
224290
appctx_values,
225291
&g_coreclr_handle,
226292
&g_coreclr_domainId
227293
);
228-
LOG_INFO ("coreclr_initialize returned %d", rv);
294+
LOG_INFO ("coreclr_initialize returned 0x%x", rv);
229295
return rv;
230296
}
231297

@@ -237,7 +303,7 @@ Java_net_dot_MonoRunner_setEnv (JNIEnv* env, jobject thiz, jstring j_key, jstrin
237303

238304
const char *key = (*env)->GetStringUTFChars(env, j_key, 0);
239305
const char *val = (*env)->GetStringUTFChars(env, j_value, 0);
240-
306+
241307
LOG_INFO ("Setting env: %s=%s", key, val);
242308
setenv (key, val, true);
243309
(*env)->ReleaseStringUTFChars(env, j_key, key);
@@ -270,7 +336,7 @@ int
270336
Java_net_dot_MonoRunner_execEntryPoint (JNIEnv* env, jobject thiz, jstring j_entryPointLibName, jobjectArray j_args)
271337
{
272338
LOG_INFO("Java_net_dot_MonoRunner_execEntryPoint (CoreCLR):");
273-
339+
274340
if ((g_bundle_path == NULL) || (g_executable_path == NULL))
275341
{
276342
LOG_ERROR("Bundle path or executable path not set");

0 commit comments

Comments
 (0)