Skip to content

Commit f7ed149

Browse files
authored
Fix a few idempotency and use-after-free issues (#15)
1 parent 24370ff commit f7ed149

File tree

4 files changed

+122
-10
lines changed

4 files changed

+122
-10
lines changed

Include/AndroidExtensions/Globals.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
#pragma once
22

33
#include <jni.h>
4+
#include <android/asset_manager_jni.h>
45
#include <arcana/containers/ticketed_collection.h>
56
#include "JavaWrappers.h"
67

78
namespace android::global
89
{
910
void Initialize(JavaVM* javaVM, jobject appContext);
11+
// Overload supporting headless scenarios without a Context.
12+
// Safe to call multiple times (e.g., hot reloads).
13+
void Initialize(JavaVM* javaVM, jobject appContext, jobject assetManager);
1014

1115
JNIEnv* GetEnvForCurrentThread();
1216

1317
android::content::Context GetAppContext();
1418

19+
void SetAssetManager(jobject assetManager);
20+
AAssetManager* GetAssetManager();
21+
1522
android::app::Activity GetCurrentActivity();
1623
void SetCurrentActivity(jobject currentActivity);
1724
using AppStateChangedCallback = std::function<void()>;

Include/AndroidExtensions/StdoutLogger.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ namespace android::StdoutLogger
55
{
66
void Start();
77
void Stop();
8-
}
8+
bool IsStarted();
9+
}

Source/Globals.cpp

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include <AndroidExtensions/Globals.h>
2+
#include <android/asset_manager_jni.h>
3+
#include <jni.h>
24
#include <stdexcept>
35

46
namespace android::global
@@ -8,6 +10,8 @@ namespace android::global
810
JavaVM* g_javaVM{};
911
jobject g_appContext{};
1012
jobject g_currentActivity{};
13+
jobject g_assetManagerObject{};
14+
AAssetManager* g_assetManager{};
1115

1216
thread_local struct Env final
1317
{
@@ -57,9 +61,39 @@ namespace android::global
5761
}
5862

5963
void Initialize(JavaVM* javaVM, jobject context)
64+
{
65+
Initialize(javaVM, context, nullptr);
66+
}
67+
68+
void Initialize(JavaVM* javaVM, jobject context, jobject assetManager)
6069
{
6170
g_javaVM = javaVM;
62-
g_appContext = GetEnvForCurrentThread()->NewGlobalRef(android::content::Context{context}.getApplicationContext());
71+
JNIEnv* env = GetEnvForCurrentThread();
72+
73+
if (g_appContext != nullptr)
74+
{
75+
env->DeleteGlobalRef(g_appContext);
76+
g_appContext = nullptr;
77+
}
78+
79+
if (context != nullptr)
80+
{
81+
g_appContext = env->NewGlobalRef(
82+
android::content::Context{context}.getApplicationContext());
83+
}
84+
85+
if (assetManager != nullptr)
86+
{
87+
SetAssetManager(assetManager);
88+
}
89+
else if (context != nullptr)
90+
{
91+
SetAssetManager(android::content::Context{context}.getAssets());
92+
}
93+
else
94+
{
95+
SetAssetManager(nullptr);
96+
}
6397
}
6498

6599
JNIEnv* GetEnvForCurrentThread()
@@ -127,4 +161,29 @@ namespace android::global
127161
{
128162
return g_requestPermissionsResultEvent.AddHandler(std::move(onAddRequestPermissionsResult));
129163
}
164+
165+
void SetAssetManager(jobject assetManager)
166+
{
167+
JNIEnv* env = GetEnvForCurrentThread();
168+
169+
if (g_assetManagerObject != nullptr)
170+
{
171+
env->DeleteGlobalRef(g_assetManagerObject);
172+
g_assetManagerObject = nullptr;
173+
}
174+
175+
if (assetManager == nullptr)
176+
{
177+
g_assetManager = nullptr;
178+
return;
179+
}
180+
181+
g_assetManagerObject = env->NewGlobalRef(assetManager);
182+
g_assetManager = AAssetManager_fromJava(env, g_assetManagerObject);
183+
}
184+
185+
AAssetManager* GetAssetManager()
186+
{
187+
return g_assetManager;
188+
}
130189
}

Source/StdoutLogger.cpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
#include <stdio.h>
55
#include <stdlib.h>
66
#include <unistd.h>
7+
#include <mutex>
78

89
namespace
910
{
10-
int fd_stdout[2];
11-
int fd_stderr[2];
11+
std::mutex g_stateMutex;
12+
bool g_started = false;
13+
int fd_stdout[2] = {-1, -1};
14+
int fd_stderr[2] = {-1, -1};
1215

1316
void thread_func(int fd, int prio)
1417
{
@@ -65,16 +68,58 @@ namespace android::StdoutLogger
6568
{
6669
void Start()
6770
{
71+
std::lock_guard<std::mutex> lock(g_stateMutex);
72+
73+
if (g_started)
74+
{
75+
return;
76+
}
77+
6878
redirect(fd_stdout, fileno(stdout), thread_func_stdout);
6979
redirect(fd_stderr, fileno(stderr), thread_func_stderr);
80+
81+
g_started = true;
7082
}
7183

7284
void Stop()
7385
{
74-
close(fd_stdout[1]);
75-
close(fd_stdout[0]);
86+
std::lock_guard<std::mutex> lock(g_stateMutex);
87+
88+
if (!g_started)
89+
{
90+
return;
91+
}
92+
93+
g_started = false;
94+
95+
if (fd_stdout[1] != -1)
96+
{
97+
close(fd_stdout[1]);
98+
fd_stdout[1] = -1;
99+
}
76100

77-
close(fd_stderr[1]);
78-
close(fd_stderr[0]);
79-
}
80-
}
101+
if (fd_stdout[0] != -1)
102+
{
103+
close(fd_stdout[0]);
104+
fd_stdout[0] = -1;
105+
}
106+
107+
if (fd_stderr[1] != -1)
108+
{
109+
close(fd_stderr[1]);
110+
fd_stderr[1] = -1;
111+
}
112+
113+
if (fd_stderr[0] != -1)
114+
{
115+
close(fd_stderr[0]);
116+
fd_stderr[0] = -1;
117+
}
118+
}
119+
120+
bool IsStarted()
121+
{
122+
std::lock_guard<std::mutex> lock(g_stateMutex);
123+
return g_started;
124+
}
125+
}

0 commit comments

Comments
 (0)