Merge Android C89 fixes from Eric Wing.

This commit is contained in:
Ryan C. Gordon 2016-02-19 00:24:00 -05:00
commit 03f9711797
3 changed files with 123 additions and 62 deletions

View file

@ -561,6 +561,7 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i
{ {
jboolean audioBufferStereo; jboolean audioBufferStereo;
int audioBufferFrames; int audioBufferFrames;
jboolean isCopy;
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
@ -602,7 +603,7 @@ int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, i
return 0; return 0;
} }
jboolean isCopy = JNI_FALSE; isCopy = JNI_FALSE;
if (audioBuffer16Bit) { if (audioBuffer16Bit) {
audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy);
audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer); audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer);
@ -654,10 +655,12 @@ void Android_JNI_CloseAudioDevice(void)
/* If the parameter silent is truthy then SDL_SetError() will not be called. */ /* If the parameter silent is truthy then SDL_SetError() will not be called. */
static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
{ {
SDL_assert(LocalReferenceHolder_IsActive());
JNIEnv *mEnv = Android_JNI_GetEnv(); JNIEnv *mEnv = Android_JNI_GetEnv();
jthrowable exception;
jthrowable exception = (*mEnv)->ExceptionOccurred(mEnv); SDL_assert(LocalReferenceHolder_IsActive());
exception = (*mEnv)->ExceptionOccurred(mEnv);
if (exception != NULL) { if (exception != NULL) {
jmethodID mid; jmethodID mid;
@ -667,13 +670,16 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
if (!silent) { if (!silent) {
jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception); jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception);
jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class"); jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class");
jstring exceptionName;
const char* exceptionNameUTF8;
jstring exceptionMessage;
mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;"); mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;");
jstring exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid); exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid);
const char* exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0); exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0);
mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;"); mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;");
jstring exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid); exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid);
if (exceptionMessage != NULL) { if (exceptionMessage != NULL) {
const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0); const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0);
@ -856,6 +862,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx,
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
JNIEnv *mEnv = Android_JNI_GetEnv(); JNIEnv *mEnv = Android_JNI_GetEnv();
int retval; int retval;
jstring fileNameJString;
if (!LocalReferenceHolder_Init(&refs, mEnv)) { if (!LocalReferenceHolder_Init(&refs, mEnv)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
@ -867,7 +874,7 @@ int Android_JNI_FileOpen(SDL_RWops* ctx,
return -1; return -1;
} }
jstring fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName); fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName);
ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString); ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString);
ctx->hidden.androidio.inputStreamRef = NULL; ctx->hidden.androidio.inputStreamRef = NULL;
ctx->hidden.androidio.readableByteChannelRef = NULL; ctx->hidden.androidio.readableByteChannelRef = NULL;
@ -886,10 +893,11 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
if (ctx->hidden.androidio.assetFileDescriptorRef) { if (ctx->hidden.androidio.assetFileDescriptorRef) {
size_t bytesMax = size * maxnum; size_t bytesMax = size * maxnum;
size_t result;
if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) { if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) {
bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position; bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position;
} }
size_t result = read(ctx->hidden.androidio.fd, buffer, bytesMax ); result = read(ctx->hidden.androidio.fd, buffer, bytesMax );
if (result > 0) { if (result > 0) {
ctx->hidden.androidio.position += result; ctx->hidden.androidio.position += result;
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
@ -901,19 +909,23 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer,
jlong bytesRemaining = (jlong) (size * maxnum); jlong bytesRemaining = (jlong) (size * maxnum);
jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position); jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position);
int bytesRead = 0; int bytesRead = 0;
JNIEnv *mEnv;
jobject readableByteChannel;
jmethodID readMethod;
jobject byteBuffer;
/* Don't read more bytes than those that remain in the file, otherwise we get an exception */ /* Don't read more bytes than those that remain in the file, otherwise we get an exception */
if (bytesRemaining > bytesMax) bytesRemaining = bytesMax; if (bytesRemaining > bytesMax) bytesRemaining = bytesMax;
JNIEnv *mEnv = Android_JNI_GetEnv(); mEnv = Android_JNI_GetEnv();
if (!LocalReferenceHolder_Init(&refs, mEnv)) { if (!LocalReferenceHolder_Init(&refs, mEnv)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
return 0; return 0;
} }
jobject readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef; readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef;
jmethodID readMethod = (jmethodID)ctx->hidden.androidio.readMethod; readMethod = (jmethodID)ctx->hidden.androidio.readMethod;
jobject byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining); byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining);
while (bytesRemaining > 0) { while (bytesRemaining > 0) {
/* result = readableByteChannel.read(...); */ /* result = readableByteChannel.read(...); */
@ -1003,6 +1015,7 @@ Sint64 Android_JNI_FileSize(SDL_RWops* ctx)
Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
{ {
if (ctx->hidden.androidio.assetFileDescriptorRef) { if (ctx->hidden.androidio.assetFileDescriptorRef) {
off_t ret;
switch (whence) { switch (whence) {
case RW_SEEK_SET: case RW_SEEK_SET:
if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size;
@ -1021,11 +1034,12 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
} }
whence = SEEK_SET; whence = SEEK_SET;
off_t ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET); ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET);
if (ret == -1) return -1; if (ret == -1) return -1;
ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset; ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset;
} else { } else {
Sint64 newPosition; Sint64 newPosition;
Sint64 movement;
switch (whence) { switch (whence) {
case RW_SEEK_SET: case RW_SEEK_SET:
@ -1049,17 +1063,18 @@ Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence)
newPosition = ctx->hidden.androidio.size; newPosition = ctx->hidden.androidio.size;
} }
Sint64 movement = newPosition - ctx->hidden.androidio.position; movement = newPosition - ctx->hidden.androidio.position;
if (movement > 0) { if (movement > 0) {
unsigned char buffer[4096]; unsigned char buffer[4096];
/* The easy case where we're seeking forwards */ /* The easy case where we're seeking forwards */
while (movement > 0) { while (movement > 0) {
Sint64 amount = sizeof (buffer); Sint64 amount = sizeof (buffer);
size_t result;
if (amount > movement) { if (amount > movement) {
amount = movement; amount = movement;
} }
size_t result = Android_JNI_FileRead(ctx, buffer, 1, amount); result = Android_JNI_FileRead(ctx, buffer, 1, amount);
if (result <= 0) { if (result <= 0) {
/* Failed to read/skip the required amount, so fail */ /* Failed to read/skip the required amount, so fail */
return -1; return -1;
@ -1092,21 +1107,23 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
JNIEnv* env = Android_JNI_GetEnv(); JNIEnv* env = Android_JNI_GetEnv();
jobject retval = NULL; jobject retval = NULL;
jstring service;
jmethodID mid;
jobject context;
jobject manager;
if (!LocalReferenceHolder_Init(&refs, env)) { if (!LocalReferenceHolder_Init(&refs, env)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
return NULL; return NULL;
} }
jstring service = (*env)->NewStringUTF(env, name); service = (*env)->NewStringUTF(env, name);
jmethodID mid;
mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
mid = (*env)->GetMethodID(env, mActivityClass, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;"); mid = (*env)->GetMethodID(env, mActivityClass, "getSystemServiceFromUiThread", "(Ljava/lang/String;)Ljava/lang/Object;");
jobject manager = (*env)->CallObjectMethod(env, context, mid, service); manager = (*env)->CallObjectMethod(env, context, mid, service);
(*env)->DeleteLocalRef(env, service); (*env)->DeleteLocalRef(env, service);
@ -1118,11 +1135,12 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
#define SETUP_CLIPBOARD(error) \ #define SETUP_CLIPBOARD(error) \
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \ struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); \
JNIEnv* env = Android_JNI_GetEnv(); \ JNIEnv* env = Android_JNI_GetEnv(); \
jobject clipboard; \
if (!LocalReferenceHolder_Init(&refs, env)) { \ if (!LocalReferenceHolder_Init(&refs, env)) { \
LocalReferenceHolder_Cleanup(&refs); \ LocalReferenceHolder_Cleanup(&refs); \
return error; \ return error; \
} \ } \
jobject clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \ clipboard = Android_JNI_GetSystemServiceObject("clipboard"); \
if (!clipboard) { \ if (!clipboard) { \
LocalReferenceHolder_Cleanup(&refs); \ LocalReferenceHolder_Cleanup(&refs); \
return error; \ return error; \
@ -1133,14 +1151,17 @@ static jobject Android_JNI_GetSystemServiceObject(const char* name)
int Android_JNI_SetClipboardText(const char* text) int Android_JNI_SetClipboardText(const char* text)
{ {
/* Watch out for C89 scoping rules because of the macro */
SETUP_CLIPBOARD(-1) SETUP_CLIPBOARD(-1)
/* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
{
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V"); jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "setText", "(Ljava/lang/CharSequence;)V");
jstring string = (*env)->NewStringUTF(env, text); jstring string = (*env)->NewStringUTF(env, text);
(*env)->CallVoidMethod(env, clipboard, mid, string); (*env)->CallVoidMethod(env, clipboard, mid, string);
(*env)->DeleteGlobalRef(env, clipboard); (*env)->DeleteGlobalRef(env, clipboard);
(*env)->DeleteLocalRef(env, string); (*env)->DeleteLocalRef(env, string);
}
CLEANUP_CLIPBOARD(); CLEANUP_CLIPBOARD();
return 0; return 0;
@ -1148,15 +1169,20 @@ int Android_JNI_SetClipboardText(const char* text)
char* Android_JNI_GetClipboardText(void) char* Android_JNI_GetClipboardText(void)
{ {
/* Watch out for C89 scoping rules because of the macro */
SETUP_CLIPBOARD(SDL_strdup("")) SETUP_CLIPBOARD(SDL_strdup(""))
/* Nest the following in a scope to avoid C89 declaration rules triggered by the macro */
{
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;"); jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "getText", "()Ljava/lang/CharSequence;");
jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid); jobject sequence = (*env)->CallObjectMethod(env, clipboard, mid);
(*env)->DeleteGlobalRef(env, clipboard); (*env)->DeleteGlobalRef(env, clipboard);
if (sequence) { if (sequence) {
jstring string;
const char* utf;
mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;"); mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, sequence), "toString", "()Ljava/lang/String;");
jstring string = (jstring)((*env)->CallObjectMethod(env, sequence, mid)); string = (jstring)((*env)->CallObjectMethod(env, sequence, mid));
const char* utf = (*env)->GetStringUTFChars(env, string, 0); utf = (*env)->GetStringUTFChars(env, string, 0);
if (utf) { if (utf) {
char* text = SDL_strdup(utf); char* text = SDL_strdup(utf);
(*env)->ReleaseStringUTFChars(env, string, utf); (*env)->ReleaseStringUTFChars(env, string, utf);
@ -1166,7 +1192,7 @@ char* Android_JNI_GetClipboardText(void)
return text; return text;
} }
} }
}
CLEANUP_CLIPBOARD(); CLEANUP_CLIPBOARD();
return SDL_strdup(""); return SDL_strdup("");
@ -1174,10 +1200,13 @@ char* Android_JNI_GetClipboardText(void)
SDL_bool Android_JNI_HasClipboardText(void) SDL_bool Android_JNI_HasClipboardText(void)
{ {
jmethodID mid;
jboolean has;
/* Watch out for C89 scoping rules because of the macro */
SETUP_CLIPBOARD(SDL_FALSE) SETUP_CLIPBOARD(SDL_FALSE)
jmethodID mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z"); mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, clipboard), "hasText", "()Z");
jboolean has = (*env)->CallBooleanMethod(env, clipboard, mid); has = (*env)->CallBooleanMethod(env, clipboard, mid);
(*env)->DeleteGlobalRef(env, clipboard); (*env)->DeleteGlobalRef(env, clipboard);
CLEANUP_CLIPBOARD(); CLEANUP_CLIPBOARD();
@ -1194,49 +1223,61 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
{ {
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
JNIEnv* env = Android_JNI_GetEnv(); JNIEnv* env = Android_JNI_GetEnv();
jmethodID mid;
jobject context;
jstring action;
jclass cls;
jobject filter;
jobject intent;
jstring iname;
jmethodID imid;
jstring bname;
jmethodID bmid;
if (!LocalReferenceHolder_Init(&refs, env)) { if (!LocalReferenceHolder_Init(&refs, env)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
return -1; return -1;
} }
jmethodID mid;
mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;");
jobject context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid);
jstring action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED");
jclass cls = (*env)->FindClass(env, "android/content/IntentFilter"); cls = (*env)->FindClass(env, "android/content/IntentFilter");
mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
jobject filter = (*env)->NewObject(env, cls, mid, action); filter = (*env)->NewObject(env, cls, mid, action);
(*env)->DeleteLocalRef(env, action); (*env)->DeleteLocalRef(env, action);
mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;");
jobject intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter);
(*env)->DeleteLocalRef(env, filter); (*env)->DeleteLocalRef(env, filter);
cls = (*env)->GetObjectClass(env, intent); cls = (*env)->GetObjectClass(env, intent);
jstring iname; imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
jmethodID imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I");
/* Watch out for C89 scoping rules because of the macro */
#define GET_INT_EXTRA(var, key) \ #define GET_INT_EXTRA(var, key) \
int var; \
iname = (*env)->NewStringUTF(env, key); \ iname = (*env)->NewStringUTF(env, key); \
int var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \
(*env)->DeleteLocalRef(env, iname); (*env)->DeleteLocalRef(env, iname);
jstring bname; bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
jmethodID bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z");
/* Watch out for C89 scoping rules because of the macro */
#define GET_BOOL_EXTRA(var, key) \ #define GET_BOOL_EXTRA(var, key) \
int var; \
bname = (*env)->NewStringUTF(env, key); \ bname = (*env)->NewStringUTF(env, key); \
int var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \
(*env)->DeleteLocalRef(env, bname); (*env)->DeleteLocalRef(env, bname);
if (plugged) { if (plugged) {
/* Watch out for C89 scoping rules because of the macro */
GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */ GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */
if (plug == -1) { if (plug == -1) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
@ -1248,6 +1289,7 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
} }
if (charged) { if (charged) {
/* Watch out for C89 scoping rules because of the macro */
GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */ GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */
if (status == -1) { if (status == -1) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
@ -1267,8 +1309,20 @@ int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seco
} }
if (percent) { if (percent) {
GET_INT_EXTRA(level, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ int level;
GET_INT_EXTRA(scale, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ int scale;
/* Watch out for C89 scoping rules because of the macro */
{
GET_INT_EXTRA(level_temp, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */
level = level_temp;
}
/* Watch out for C89 scoping rules because of the macro */
{
GET_INT_EXTRA(scale_temp, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */
scale = scale_temp;
}
if ((level == -1) || (scale == -1)) { if ((level == -1) || (scale == -1)) {
LocalReferenceHolder_Cleanup(&refs); LocalReferenceHolder_Cleanup(&refs);
return -1; return -1;
@ -1321,14 +1375,16 @@ void Android_JNI_PollInputDevices(void)
int Android_JNI_SendMessage(int command, int param) int Android_JNI_SendMessage(int command, int param)
{ {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
jmethodID mid;
jboolean success;
if (!env) { if (!env) {
return -1; return -1;
} }
jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z"); mid = (*env)->GetStaticMethodID(env, mActivityClass, "sendMessage", "(II)Z");
if (!mid) { if (!mid) {
return -1; return -1;
} }
jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param); success = (*env)->CallStaticBooleanMethod(env, mActivityClass, mid, command, param);
return success ? 0 : -1; return success ? 0 : -1;
} }
@ -1340,11 +1396,12 @@ void Android_JNI_SuspendScreenSaver(SDL_bool suspend)
void Android_JNI_ShowTextInput(SDL_Rect *inputRect) void Android_JNI_ShowTextInput(SDL_Rect *inputRect)
{ {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
jmethodID mid;
if (!env) { if (!env) {
return; return;
} }
jmethodID mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z"); mid = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIII)Z");
if (!mid) { if (!mid) {
return; return;
} }

View file

@ -323,6 +323,7 @@ Android_RemoveJoystick(int device_id)
{ {
SDL_joylist_item *item = SDL_joylist; SDL_joylist_item *item = SDL_joylist;
SDL_joylist_item *prev = NULL; SDL_joylist_item *prev = NULL;
int retval;
#if !SDL_EVENTS_DISABLED #if !SDL_EVENTS_DISABLED
SDL_Event event; SDL_Event event;
#endif #endif
@ -340,6 +341,7 @@ Android_RemoveJoystick(int device_id)
return -1; return -1;
} }
retval = item->device_instance;
if (item->joystick) { if (item->joystick) {
item->joystick->hwdata = NULL; item->joystick->hwdata = NULL;
} }

View file

@ -22,6 +22,8 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
int i; int i;
int argc; int argc;
int status; int status;
int len;
char** argv;
/* This interface could expand with ABI negotiation, callbacks, etc. */ /* This interface could expand with ABI negotiation, callbacks, etc. */
SDL_Android_Init(env, cls); SDL_Android_Init(env, cls);
@ -30,8 +32,8 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
/* Prepare the arguments. */ /* Prepare the arguments. */
int len = (*env)->GetArrayLength(env, array); len = (*env)->GetArrayLength(env, array);
char* argv[1 + len + 1]; argv = SDL_stack_alloc(char*, 1 + len + 1);
argc = 0; argc = 0;
/* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start
@ -66,7 +68,7 @@ JNIEXPORT int JNICALL Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jc
for (i = 0; i < argc; ++i) { for (i = 0; i < argc; ++i) {
SDL_free(argv[i]); SDL_free(argv[i]);
} }
SDL_stack_free(argv);
/* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
/* exit(status); */ /* exit(status); */