Skip to content

Commit 5a09a10

Browse files
committed
Finalize Android Java backend.
1 parent 3817bac commit 5a09a10

4 files changed

Lines changed: 67 additions & 12 deletions

File tree

src/android/AndroidClient.cpp

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include <dlfcn.h>
99

10-
std::string replace(const std::string &str, const std::string &from, const std::string &to)
10+
static std::string replace(const std::string &str, const std::string &from, const std::string &to)
1111
{
1212
std::stringstream ss;
1313
size_t oldpos = 0;
@@ -29,17 +29,19 @@ std::string replace(const std::string &str, const std::string &from, const std::
2929
return ss.str();
3030
}
3131

32-
jstring newStringUTF(JNIEnv *env, const std::string &str)
32+
static jstring newStringUTF(JNIEnv *env, const std::string &str)
3333
{
34+
// We want std::string that contains null byte, hence length of 1.
3435
static std::string null("", 1);
3536

3637
std::string newStr = replace(str, null, "\xC0\x80");
3738
jstring jstr = env->NewStringUTF(newStr.c_str());
3839
return jstr;
3940
}
4041

41-
std::string getStringUTF(JNIEnv *env, jstring str)
42+
static std::string getStringUTF(JNIEnv *env, jstring str)
4243
{
44+
// We want std::string that contains null byte, hence length of 1.
4345
static std::string null("", 1);
4446

4547
const char *c = env->GetStringUTFChars(str, nullptr);
@@ -55,19 +57,27 @@ AndroidClient::AndroidClient()
5557
{
5658
// Look for SDL_AndroidGetJNIEnv
5759
SDL_AndroidGetJNIEnv = (decltype(SDL_AndroidGetJNIEnv)) dlsym(RTLD_DEFAULT, "SDL_AndroidGetJNIEnv");
60+
// Look for SDL_AndroidGetActivity
61+
SDL_AndroidGetActivity = (decltype(SDL_AndroidGetActivity)) dlsym(RTLD_DEFAULT, "SDL_AndroidGetActivity");
5862
}
5963

6064
bool AndroidClient::valid() const
6165
{
62-
if (SDL_AndroidGetJNIEnv)
66+
if (SDL_AndroidGetJNIEnv && SDL_AndroidGetActivity)
6367
{
6468
JNIEnv *env = SDL_AndroidGetJNIEnv();
6569

6670
if (env)
6771
{
68-
jclass httpsClass = env->FindClass("org/love2d/luahttps/LuaHTTPS");
72+
jclass httpsClass = getHTTPSClass();
73+
if (env->ExceptionCheck())
74+
{
75+
env->ExceptionClear();
76+
return false;
77+
}
78+
6979
env->DeleteLocalRef(httpsClass);
70-
return httpsClass != nullptr;
80+
return true;
7181
}
7282
}
7383

@@ -77,7 +87,7 @@ bool AndroidClient::valid() const
7787
HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req)
7888
{
7989
JNIEnv *env = SDL_AndroidGetJNIEnv();
80-
jclass httpsClass = env->FindClass("org/love2d/luahttps/LuaHTTPS");
90+
jclass httpsClass = getHTTPSClass();
8191

8292
if (httpsClass == nullptr)
8393
{
@@ -172,4 +182,31 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req)
172182
return response;
173183
}
174184

185+
jclass AndroidClient::getHTTPSClass() const
186+
{
187+
JNIEnv *env = SDL_AndroidGetJNIEnv();
188+
189+
jclass classLoaderClass = env->FindClass("java/lang/ClassLoader");
190+
jmethodID loadClass = env->GetMethodID(classLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
191+
192+
jobject activity = SDL_AndroidGetActivity();
193+
194+
if (activity == nullptr)
195+
return nullptr;
196+
197+
jclass gameActivity = env->GetObjectClass(activity);
198+
jmethodID getLoader = env->GetMethodID(gameActivity, "getClassLoader", "()Ljava/lang/ClassLoader;");
199+
jobject classLoader = env->CallObjectMethod(activity, getLoader);
200+
201+
jstring httpsClassName = env->NewStringUTF("org.love2d.luahttps.LuaHTTPS");
202+
jclass httpsClass = (jclass) env->CallObjectMethod(classLoader, loadClass, httpsClassName);
203+
204+
env->DeleteLocalRef(gameActivity);
205+
env->DeleteLocalRef(httpsClassName);
206+
env->DeleteLocalRef(activity);
207+
env->DeleteLocalRef(classLoaderClass);
208+
209+
return httpsClass;
210+
}
211+
175212
#endif

src/android/AndroidClient.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class AndroidClient: public HTTPSClient
1818

1919
private:
2020
JNIEnv *(*SDL_AndroidGetJNIEnv)();
21+
jobject (*SDL_AndroidGetActivity)();
22+
23+
jclass getHTTPSClass() const;
2124
};
2225

2326
#endif

src/android/java/org/love2d/luahttps/LuaHTTPS.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.net.HttpURLConnection;
1313
import java.net.MalformedURLException;
1414
import java.net.URL;
15+
import java.util.ArrayList;
1516
import java.util.HashMap;
1617
import java.util.List;
1718
import java.util.Map;
@@ -39,39 +40,51 @@ public void reset() {
3940
headers.clear();
4041
}
4142

43+
@Keep
4244
public void setUrl(String url) {
4345
urlString = url;
4446
}
4547

48+
@Keep
4649
public void setPostData(byte[] postData) {
4750
this.postData = postData;
4851
}
4952

53+
@Keep
5054
public void addHeader(String key, String value) {
5155
headers.put(key, value);
5256
}
5357

58+
@Keep
5459
public String[] getInterleavedHeaders() {
55-
String[] result = new String[headers.size() * 2];
56-
int i = 0;
60+
ArrayList<String> resultInterleaved = new ArrayList<String>();
5761

5862
for (Map.Entry<String, String> header: headers.entrySet()) {
59-
result[i * 2] = header.getKey();
60-
result[i * 2 + 1] = header.getValue();
61-
i++;
63+
String key = header.getKey();
64+
String value = header.getValue();
65+
66+
if (key != null && value != null) {
67+
resultInterleaved.add(key);
68+
resultInterleaved.add(value);
69+
}
6270
}
6371

72+
String[] result = new String[resultInterleaved.size()];
73+
resultInterleaved.toArray(result);
6474
return result;
6575
}
6676

77+
@Keep
6778
public int getResponseCode() {
6879
return responseCode;
6980
}
7081

82+
@Keep
7183
public byte[] getResponse() {
7284
return response;
7385
}
7486

87+
@Keep
7588
public boolean request() {
7689
if (urlString == null) {
7790
return false;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define USE_ANDROID_BACKEND
2+
#define DLLEXPORT __attribute__((visibility ("default")))

0 commit comments

Comments
 (0)