Skip to content

Commit 791e644

Browse files
committed
Share environment setup code between CoreCLR and NativeAOT
1 parent f3e1b3b commit 791e644

File tree

12 files changed

+110
-70
lines changed

12 files changed

+110
-70
lines changed

src/Microsoft.Android.Runtime.NativeAOT/Android.Runtime.NativeAOT/JavaInteropRuntime.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ static void JNI_OnUnload (IntPtr vm, IntPtr reserved)
4141
}
4242

4343
[DllImport("xa-internal-api")]
44-
static extern void XA_Host_NativeAOT_OnInit ();
44+
static extern void XA_Host_NativeAOT_OnInit (IntPtr language, IntPtr filesDir, IntPtr cacheDir);
4545

4646
// symbol name from `$(IntermediateOutputPath)obj/Release/osx-arm64/h-classes/net_dot_jni_hello_JavaInteropRuntime.h`
4747
[UnmanagedCallersOnly (EntryPoint="Java_net_dot_jni_nativeaot_JavaInteropRuntime_init")]
48-
static void init (IntPtr jnienv, IntPtr klass, IntPtr classLoader)
48+
static void init (IntPtr jnienv, IntPtr klass, IntPtr classLoader, IntPtr language, IntPtr filesDir, IntPtr cacheDir)
4949
{
5050
JniTransition transition = default;
5151
try {
@@ -65,7 +65,7 @@ static void init (IntPtr jnienv, IntPtr klass, IntPtr classLoader)
6565

6666
// Entry point into Mono.Android.dll
6767
JNIEnvInit.InitializeJniRuntime (runtime);
68-
XA_Host_NativeAOT_OnInit ();
68+
XA_Host_NativeAOT_OnInit (language, filesDir, cacheDir);
6969

7070
transition = new JniTransition (jnienv);
7171

src/Xamarin.Android.Build.Tasks/Resources/JavaInteropRuntime.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ public class JavaInteropRuntime {
1111
private JavaInteropRuntime() {
1212
}
1313

14-
public static native void init(ClassLoader classLoader);
14+
public static native void init(ClassLoader classLoader, String language, String filesDir, String cacheDir);
1515
}

src/Xamarin.Android.Build.Tasks/Resources/NativeAotRuntimeProvider.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package net.dot.jni.nativeaot;
22

3+
import java.util.Locale;
34
import android.system.ErrnoException;
45
import android.system.Os;
56
import android.util.Log;
@@ -27,20 +28,14 @@ public void attachInfo(android.content.Context context, android.content.pm.Provi
2728
ApplicationRegistration.Context = context;
2829
}
2930

30-
// Set environment variables
31-
try {
32-
String filesDir = context.getFilesDir().getAbsolutePath();
33-
String cacheDir = context.getCacheDir().getAbsolutePath();
34-
Os.setenv("HOME", filesDir, true);
35-
Os.setenv("TMPDIR", cacheDir, true);
36-
} catch (ErrnoException e) {
37-
Log.e(TAG, "Failed to set environment variables", e);
38-
}
39-
40-
ClassLoader loader = context.getClassLoader ();
31+
ClassLoader loader = context.getClassLoader ();
32+
Locale locale = Locale.getDefault ();
33+
String language = locale.getLanguage () + "-" + locale.getCountry ();
34+
String filesDir = context.getFilesDir().getAbsolutePath();
35+
String cacheDir = context.getCacheDir().getAbsolutePath();
4136

4237
// Initialize .NET runtime
43-
JavaInteropRuntime.init(loader);
38+
JavaInteropRuntime.init(loader, language, filesDir, cacheDir);
4439
// NOTE: only required for custom applications
4540
ApplicationRegistration.registerApplications();
4641
super.attachInfo (context, info);
@@ -70,4 +65,4 @@ public int delete(android.net.Uri uri, String where, String[] whereArgs) {
7065
public int update(android.net.Uri uri, android.content.ContentValues values, String where, String[] whereArgs) {
7166
throw new RuntimeException ("This operation is not supported.");
7267
}
73-
}
68+
}

src/native/clr/host/host.cc

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <host/gc-bridge.hh>
1616
#include <host/fastdev-assemblies.hh>
1717
#include <host/host.hh>
18+
#include <host/host-environment-clr.hh>
1819
#include <host/host-jni.hh>
1920
#include <host/host-util.hh>
2021
#include <host/os-bridge.hh>
@@ -285,35 +286,6 @@ void Host::gather_assemblies_and_libraries (jstring_array_wrapper& runtimeApks,
285286
}
286287
}
287288

288-
void Host::create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept
289-
{
290-
static_local_string<SENSIBLE_PATH_MAX> dir (home_len + relative_path.length ());
291-
Util::path_combine (dir, home.get_string_view (), relative_path);
292-
293-
log_debug (LOG_DEFAULT, "Creating XDG directory: {}"sv, optional_string (dir.get ()));
294-
int rv = Util::create_directory (dir.get (), Constants::DEFAULT_DIRECTORY_MODE);
295-
if (rv < 0 && errno != EEXIST) {
296-
log_warn (LOG_DEFAULT, "Failed to create XDG directory {}. {}"sv, optional_string (dir.get ()), strerror (errno));
297-
}
298-
299-
if (!environment_variable_name.empty ()) {
300-
setenv (environment_variable_name.data (), dir.get (), 1);
301-
}
302-
}
303-
304-
void Host::create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept
305-
{
306-
size_t home_len = strlen (homeDir.get_cstr ());
307-
308-
constexpr auto XDG_DATA_HOME = "XDG_DATA_HOME"sv;
309-
constexpr auto HOME_PATH = ".local/share"sv;
310-
create_xdg_directory (homeDir, home_len, HOME_PATH, XDG_DATA_HOME);
311-
312-
constexpr auto XDG_CONFIG_HOME = "XDG_CONFIG_HOME"sv;
313-
constexpr auto CONFIG_PATH = ".config"sv;
314-
create_xdg_directory (homeDir, home_len, CONFIG_PATH, XDG_CONFIG_HOME);
315-
}
316-
317289
[[gnu::always_inline]]
318290
auto Host::create_delegate (
319291
std::string_view const& assembly_name, std::string_view const& type_name,
@@ -434,20 +406,19 @@ void Host::Java_mono_android_Runtime_initInternal (
434406
}
435407

436408
jstring_array_wrapper applicationDirs (env, appDirs);
437-
438-
jstring_wrapper jstr (env, lang);
439-
Util::set_environment_variable ("LANG"sv, jstr);
440-
441-
jstring_wrapper &home = applicationDirs[Constants::APP_DIRS_FILES_DIR_INDEX];
442-
Util::set_environment_variable_for_directory ("TMPDIR"sv, applicationDirs[Constants::APP_DIRS_CACHE_DIR_INDEX]);
443-
Util::set_environment_variable_for_directory ("HOME"sv, home);
444-
create_xdg_directories_and_environment (home);
409+
jstring_wrapper language (env, lang);
410+
jstring_wrapper &files_dir = applicationDirs[Constants::APP_DIRS_FILES_DIR_INDEX];
411+
HostEnvironment::setup_environment (
412+
language,
413+
files_dir,
414+
applicationDirs[Constants::APP_DIRS_CACHE_DIR_INDEX]
415+
);
445416

446417
java_TimeZone = RuntimeUtil::get_class_from_runtime_field (env, runtimeClass, "java_util_TimeZone"sv, true);
447418

448419
AndroidSystem::detect_embedded_dso_mode (applicationDirs);
449420
AndroidSystem::set_running_in_emulator (isEmulator);
450-
AndroidSystem::set_primary_override_dir (home);
421+
AndroidSystem::set_primary_override_dir (files_dir);
451422
AndroidSystem::create_update_dir (AndroidSystem::get_primary_override_dir ());
452423
AndroidSystem::setup_environment ();
453424

src/native/clr/include/host/host-environment.hh

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
#pragma once
22

3+
#include <jni.h>
4+
35
#include <cerrno>
46
#include <cstdlib>
57
#include <cstring>
68
#include <string_view>
79

10+
#include <runtime-base/jni-wrappers.hh>
811
#include <runtime-base/logger.hh>
12+
#include <runtime-base/strings.hh>
13+
#include <runtime-base/util.hh>
914

1015
struct AppEnvironmentVariable;
1116

@@ -18,16 +23,19 @@ namespace xamarin::android {
1823
[[gnu::flatten, gnu::always_inline]]
1924
static void set_variable (const char *name, const char *value) noexcept
2025
{
21-
log_debug (LOG_DEFAULT, " Variable {} = '{}'", optional_string (name), optional_string (value));
22-
if (::setenv (name, value, 1) < 0) {
23-
log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
24-
}
26+
Util::set_environment_variable (name, value);
2527
}
2628

2729
[[gnu::flatten, gnu::always_inline]]
2830
static void set_variable (std::string_view const& name, std::string_view const& value) noexcept
2931
{
30-
set_variable (name.data (), value.data ());
32+
Util::set_environment_variable (name.data (), value.data ());
33+
}
34+
35+
[[gnu::flatten, gnu::always_inline]]
36+
static void set_variable (std::string_view const& name, jstring_wrapper &value) noexcept
37+
{
38+
Util::set_environment_variable (name.data (), value);
3139
}
3240

3341
[[gnu::flatten, gnu::always_inline]]
@@ -72,5 +80,47 @@ namespace xamarin::android {
7280
setter (var_name, var_value);
7381
}
7482
}
83+
84+
private:
85+
[[gnu::flatten, gnu::always_inline]]
86+
static void create_xdg_directory (jstring_wrapper &home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept
87+
{
88+
static_local_string<SENSIBLE_PATH_MAX> dir (home_len + relative_path.length ());
89+
Util::path_combine (dir, home.get_string_view (), relative_path);
90+
91+
log_debug (LOG_DEFAULT, "Creating XDG directory: {}"sv, optional_string (dir.get ()));
92+
int rv = Util::create_directory (dir.get (), Constants::DEFAULT_DIRECTORY_MODE);
93+
if (rv < 0 && errno != EEXIST) {
94+
log_warn (LOG_DEFAULT, "Failed to create XDG directory {}. {}"sv, optional_string (dir.get ()), strerror (errno));
95+
}
96+
97+
if (!environment_variable_name.empty ()) {
98+
set_variable (environment_variable_name.data (), dir.get ());
99+
}
100+
}
101+
102+
[[gnu::flatten, gnu::always_inline]]
103+
static void create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept
104+
{
105+
size_t home_len = strlen (homeDir.get_cstr ());
106+
107+
constexpr auto XDG_DATA_HOME = "XDG_DATA_HOME"sv;
108+
constexpr auto HOME_PATH = ".local/share"sv;
109+
create_xdg_directory (homeDir, home_len, HOME_PATH, XDG_DATA_HOME);
110+
111+
constexpr auto XDG_CONFIG_HOME = "XDG_CONFIG_HOME"sv;
112+
constexpr auto CONFIG_PATH = ".config"sv;
113+
create_xdg_directory (homeDir, home_len, CONFIG_PATH, XDG_CONFIG_HOME);
114+
}
115+
116+
public:
117+
[[gnu::flatten, gnu::always_inline]]
118+
static void setup_environment (jstring_wrapper &language, jstring_wrapper &files_dir, jstring_wrapper &cache_dir) noexcept
119+
{
120+
set_variable ("LANG"sv, language);
121+
Util::set_environment_variable_for_directory ("TMPDIR"sv, cache_dir);
122+
Util::set_environment_variable_for_directory ("HOME"sv, files_dir);
123+
create_xdg_directories_and_environment (files_dir);
124+
}
75125
};
76126
}

src/native/clr/include/host/host.hh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ namespace xamarin::android {
3232
}
3333

3434
private:
35-
static void create_xdg_directory (jstring_wrapper& home, size_t home_len, std::string_view const& relative_path, std::string_view const& environment_variable_name) noexcept;
36-
static void create_xdg_directories_and_environment (jstring_wrapper &homeDir) noexcept;
3735
static auto zip_scan_callback (std::string_view const& apk_path, int apk_fd, dynamic_local_string<SENSIBLE_PATH_MAX> const& entry_name, uint32_t offset, uint32_t size) -> bool;
3836
static void gather_assemblies_and_libraries (jstring_array_wrapper& runtimeApks, bool have_split_apks);
3937
static void scan_filesystem_for_assemblies_and_libraries () noexcept;

src/native/clr/include/runtime-base/util.hh

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,28 @@ namespace xamarin::android {
151151
return get_file_size_at (dirfd, file_name.data ());
152152
}
153153

154+
[[gnu::flatten, gnu::always_inline]]
155+
static void set_environment_variable (const char *name, const char *value) noexcept
156+
{
157+
log_debug (LOG_DEFAULT, "Setting environment variable {} = '{}'", optional_string (name), optional_string (value));
158+
if (::setenv (name, value, 1) < 0) {
159+
log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
160+
}
161+
}
162+
163+
[[gnu::flatten, gnu::always_inline]]
154164
static void set_environment_variable (std::string_view const& name, jstring_wrapper& value) noexcept
155165
{
156-
::setenv (name.data (), value.get_cstr (), 1);
166+
set_environment_variable (name.data (), value.get_cstr ());
157167
}
158168

169+
[[gnu::flatten, gnu::always_inline]]
170+
static void set_environment_variable (std::string_view const& name, std::string_view const& value) noexcept
171+
{
172+
set_environment_variable (name.data (), value.data ());
173+
}
174+
175+
[[gnu::flatten, gnu::always_inline]]
159176
static void set_environment_variable_for_directory (std::string_view const& name, jstring_wrapper& value, bool createDirectory, mode_t mode) noexcept
160177
{
161178
if (createDirectory) {
@@ -167,6 +184,7 @@ namespace xamarin::android {
167184
set_environment_variable (name, value);
168185
}
169186

187+
[[gnu::flatten, gnu::always_inline]]
170188
static void set_environment_variable_for_directory (std::string_view const& name, jstring_wrapper &value) noexcept
171189
{
172190
set_environment_variable_for_directory (name, value, true, Constants::DEFAULT_DIRECTORY_MODE);

src/native/nativeaot/host/host-environment.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ extern "C" {
1414
void HostEnvironment::init () noexcept
1515
{
1616
if (__naot_android_app_environment_variable_count > 0) {
17-
log_debug (LOG_DEFAULT, "Setting environment variables ({})", __naot_android_app_environment_variable_count);
1817
set_values<set_variable> (
1918
__naot_android_app_environment_variable_count,
2019
__naot_android_app_environment_variables,
@@ -26,7 +25,6 @@ void HostEnvironment::init () noexcept
2625
return;
2726
}
2827

29-
log_debug (LOG_DEFAULT, "Setting system properties ({})", __naot_android_app_system_property_count);
3028
set_values<set_system_property> (
3129
__naot_android_app_system_property_count,
3230
__naot_android_app_system_properties,

src/native/nativeaot/host/host-jni.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#include <jni.h>
2+
13
#include <host/host-jni.hh>
24
#include <host/host-nativeaot.hh>
35
#include <runtime-base/logger.hh>
@@ -9,7 +11,7 @@ auto XA_Host_NativeAOT_JNI_OnLoad (JavaVM *vm, void *reserved) -> int
911
return Host::Java_JNI_OnLoad (vm, reserved);
1012
}
1113

12-
void XA_Host_NativeAOT_OnInit ()
14+
void XA_Host_NativeAOT_OnInit (jstring language, jstring filesDir, jstring cacheDir)
1315
{
14-
Host::OnInit ();
16+
Host::OnInit (language, filesDir, cacheDir);
1517
}

src/native/nativeaot/host/host.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ auto HostCommon::Java_JNI_OnLoad (JavaVM *vm, void *reserved) noexcept -> jint
4646
return JNI_VERSION_1_6;
4747
}
4848

49-
void Host::OnInit () noexcept
49+
void Host::OnInit (jstring language, jstring filesDir, jstring cacheDir) noexcept
5050
{
5151
JNIEnv *env = OSBridge::ensure_jnienv ();
5252
jclass runtimeClass = env->FindClass ("mono/android/Runtime");
53+
54+
jstring_wrapper language_js (env, language);
55+
jstring_wrapper files_dir (env, filesDir);
56+
jstring_wrapper cache_dir (env, cacheDir);
57+
HostEnvironment::setup_environment (language_js, files_dir, cache_dir);
58+
5359
OSBridge::initialize_on_runtime_init (env, runtimeClass);
5460
GCBridge::initialize_on_runtime_init (env, runtimeClass);
5561
BridgeProcessing::naot_initialize_on_runtime_init (env);

0 commit comments

Comments
 (0)