Fixed bug 2361 - [Android] Joysticks do not have unique IDs
authorSam Lantinga <slouken@libsdl.org>
Mon, 28 Aug 2017 10:03:39 -0700
changeset 113933e57ce45a890
parent 11392 833ec9f10b80
child 11394 910be5fe412a
Fixed bug 2361 - [Android] Joysticks do not have unique IDs

David Brady

When I attempted to make a mapping file for Android gamepads, I quickly discovered that most of the ones that I have here show up as the same device (Broadcom Bluetooth HID), meaning that it was impossible to make mappings on Android, since every device looked the same.

This patch will check for the existence of the getDescriptor function added in Jelly Bean, and use it if it's there. The Android Dashboard says that the majority of Android phones should support this function, and doing it this way will not force us to bump up our API version.
android-project/src/org/libsdl/app/SDLActivity.java
src/core/android/SDL_android.c
src/core/android/SDL_android.h
src/joystick/android/SDL_sysjoystick.c
src/joystick/android/SDL_sysjoystick_c.h
     1.1 --- a/android-project/src/org/libsdl/app/SDLActivity.java	Mon Aug 28 09:54:16 2017 -0700
     1.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java	Mon Aug 28 10:03:39 2017 -0700
     1.3 @@ -182,12 +182,15 @@
     1.4          // Set up the surface
     1.5          mSurface = new SDLSurface(getApplication());
     1.6  
     1.7 -        if(Build.VERSION.SDK_INT >= 12) {
     1.8 +
     1.9 +        if(Build.VERSION.SDK_INT >= 16) {
    1.10 +            mJoystickHandler = new SDLJoystickHandler_API16();
    1.11 +        } else if(Build.VERSION.SDK_INT >= 12) {
    1.12              mJoystickHandler = new SDLJoystickHandler_API12();
    1.13 -        }
    1.14 -        else {
    1.15 +        } else {
    1.16              mJoystickHandler = new SDLJoystickHandler();
    1.17          }
    1.18 +
    1.19          mHapticHandler = new SDLHapticHandler();
    1.20  
    1.21          if (Build.VERSION.SDK_INT >= 11) {
    1.22 @@ -511,7 +514,7 @@
    1.23      public static native void onNativeClipboardChanged();
    1.24      public static native void onNativeSurfaceChanged();
    1.25      public static native void onNativeSurfaceDestroyed();
    1.26 -    public static native int nativeAddJoystick(int device_id, String name,
    1.27 +    public static native int nativeAddJoystick(int device_id, String name, String desc,
    1.28                                                 int is_accelerometer, int nbuttons,
    1.29                                                 int naxes, int nhats, int nballs);
    1.30      public static native int nativeRemoveJoystick(int device_id);
    1.31 @@ -1737,6 +1740,7 @@
    1.32      static class SDLJoystick {
    1.33          public int device_id;
    1.34          public String name;
    1.35 +        public String desc;
    1.36          public ArrayList<InputDevice.MotionRange> axes;
    1.37          public ArrayList<InputDevice.MotionRange> hats;
    1.38      }
    1.39 @@ -1770,6 +1774,7 @@
    1.40                  if (SDLActivity.isDeviceSDLJoystick(deviceIds[i])) {
    1.41                      joystick.device_id = deviceIds[i];
    1.42                      joystick.name = joystickDevice.getName();
    1.43 +                    joystick.desc = getJoystickDescriptor(joystickDevice);
    1.44                      joystick.axes = new ArrayList<InputDevice.MotionRange>();
    1.45                      joystick.hats = new ArrayList<InputDevice.MotionRange>();
    1.46  
    1.47 @@ -1788,7 +1793,7 @@
    1.48                      }
    1.49  
    1.50                      mJoysticks.add(joystick);
    1.51 -                    SDLActivity.nativeAddJoystick(joystick.device_id, joystick.name, 0, -1,
    1.52 +                    SDLActivity.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, 0, -1,
    1.53                                                    joystick.axes.size(), joystick.hats.size()/2, 0);
    1.54                  }
    1.55              }
    1.56 @@ -1856,6 +1861,25 @@
    1.57          }
    1.58          return true;
    1.59      }
    1.60 +
    1.61 +    public String getJoystickDescriptor(InputDevice joystickDevice) {
    1.62 +        return joystickDevice.getName();
    1.63 +    }
    1.64 +}
    1.65 +
    1.66 +
    1.67 +class SDLJoystickHandler_API16 extends SDLJoystickHandler_API12 {
    1.68 +
    1.69 +    @Override
    1.70 +    public String getJoystickDescriptor(InputDevice joystickDevice) {
    1.71 +        String desc = joystickDevice.getDescriptor();
    1.72 +
    1.73 +        if (desc != null && desc != "") {
    1.74 +            return desc;
    1.75 +        }
    1.76 +
    1.77 +        return super.getJoystickDescriptor(joystickDevice);
    1.78 +    }
    1.79  }
    1.80  
    1.81  class SDLGenericMotionListener_API12 implements View.OnGenericMotionListener {
     2.1 --- a/src/core/android/SDL_android.c	Mon Aug 28 09:54:16 2017 -0700
     2.2 +++ b/src/core/android/SDL_android.c	Mon Aug 28 10:03:39 2017 -0700
     2.3 @@ -84,7 +84,7 @@
     2.4  
     2.5  JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddJoystick)(
     2.6          JNIEnv* env, jclass jcls,
     2.7 -        jint device_id, jstring device_name, jint is_accelerometer,
     2.8 +        jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer,
     2.9          jint nbuttons, jint naxes, jint nhats, jint nballs);
    2.10  
    2.11  JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeRemoveJoystick)(
    2.12 @@ -365,15 +365,17 @@
    2.13  
    2.14  JNIEXPORT jint JNICALL SDL_JAVA_INTERFACE(nativeAddJoystick)(
    2.15                                      JNIEnv* env, jclass jcls,
    2.16 -                                    jint device_id, jstring device_name, jint is_accelerometer,
    2.17 +                                    jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer,
    2.18                                      jint nbuttons, jint naxes, jint nhats, jint nballs)
    2.19  {
    2.20      int retval;
    2.21      const char *name = (*env)->GetStringUTFChars(env, device_name, NULL);
    2.22 +    const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL);
    2.23  
    2.24 -    retval = Android_AddJoystick(device_id, name, (SDL_bool) is_accelerometer, nbuttons, naxes, nhats, nballs);
    2.25 +    retval = Android_AddJoystick(device_id, name, desc, (SDL_bool) is_accelerometer, nbuttons, naxes, nhats, nballs);
    2.26  
    2.27      (*env)->ReleaseStringUTFChars(env, device_name, name);
    2.28 +    (*env)->ReleaseStringUTFChars(env, device_desc, desc);
    2.29  
    2.30      return retval;
    2.31  }
     3.1 --- a/src/core/android/SDL_android.h	Mon Aug 28 09:54:16 2017 -0700
     3.2 +++ b/src/core/android/SDL_android.h	Mon Aug 28 10:03:39 2017 -0700
     3.3 @@ -35,6 +35,7 @@
     3.4  /* Interface from the SDL library into the Android Java activity */
     3.5  extern void Android_JNI_SetActivityTitle(const char *title);
     3.6  extern void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint);
     3.7 +
     3.8  extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]);
     3.9  extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect);
    3.10  extern void Android_JNI_HideTextInput(void);
     4.1 --- a/src/joystick/android/SDL_sysjoystick.c	Mon Aug 28 09:54:16 2017 -0700
     4.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Mon Aug 28 10:03:39 2017 -0700
     4.3 @@ -244,7 +244,7 @@
     4.4  
     4.5  
     4.6  int
     4.7 -Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs)
     4.8 +Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs)
     4.9  {
    4.10      SDL_JoystickGUID guid;
    4.11      SDL_joylist_item *item;
    4.12 @@ -255,7 +255,7 @@
    4.13      
    4.14      /* the GUID is just the first 16 chars of the name for now */
    4.15      SDL_zero( guid );
    4.16 -    SDL_memcpy( &guid, name, SDL_min( sizeof(guid), SDL_strlen( name ) ) );
    4.17 +    SDL_memcpy( &guid, desc, SDL_min( sizeof(guid), SDL_strlen( desc) ) );
    4.18  
    4.19      item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
    4.20      if (item == NULL) {
    4.21 @@ -356,7 +356,7 @@
    4.22      
    4.23      if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
    4.24          /* Default behavior, accelerometer as joystick */
    4.25 -        Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
    4.26 +        Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
    4.27      }
    4.28     
    4.29      return (numjoysticks);
     5.1 --- a/src/joystick/android/SDL_sysjoystick_c.h	Mon Aug 28 09:54:16 2017 -0700
     5.2 +++ b/src/joystick/android/SDL_sysjoystick_c.h	Mon Aug 28 10:03:39 2017 -0700
     5.3 @@ -32,7 +32,7 @@
     5.4  extern int Android_OnPadUp(int device_id, int keycode);
     5.5  extern int Android_OnJoy(int device_id, int axisnum, float value);
     5.6  extern int Android_OnHat(int device_id, int hat_id, int x, int y);
     5.7 -extern int Android_AddJoystick(int device_id, const char *name, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs);
     5.8 +extern int Android_AddJoystick(int device_id, const char *name, const char *desc, SDL_bool is_accelerometer, int nbuttons, int naxes, int nhats, int nballs);
     5.9  extern int Android_RemoveJoystick(int device_id);
    5.10  
    5.11  /* A linked list of available joysticks */