Allow SDL to use ReLinker if present.
authorSam Lantinga <slouken@libsdl.org>
Thu, 04 Oct 2018 16:29:17 -0700
changeset 12292f4dde3c6bae9
parent 12291 287350656743
child 12296 5b48897016d2
Allow SDL to use ReLinker if present.
This fixes issues for applications that have a large number of shared libraries
For more information, see https://github.com/KeepSafe/ReLinker for ReLinker's repository.
android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
android-project/app/src/main/java/org/libsdl/app/SDL.java
android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
     1.1 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java	Thu Oct 04 15:23:42 2018 -0700
     1.2 +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java	Thu Oct 04 16:29:17 2018 -0700
     1.3 @@ -577,7 +577,7 @@
     1.4          }
     1.5  
     1.6          // We need to skip the first byte, as that doesn't go over the air
     1.7 -	byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
     1.8 +        byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
     1.9          //Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report));
    1.10          writeCharacteristic(reportCharacteristic, actual_report);
    1.11          return report.length;
     2.1 --- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java	Thu Oct 04 15:23:42 2018 -0700
     2.2 +++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java	Thu Oct 04 16:29:17 2018 -0700
     2.3 @@ -80,14 +80,14 @@
     2.4      public HIDDeviceManager(Context context) {
     2.5          mContext = context;
     2.6  
     2.7 -	// Make sure we have the HIDAPI library loaded with the native functions
     2.8 +        // Make sure we have the HIDAPI library loaded with the native functions
     2.9          try {
    2.10 -            System.loadLibrary("hidapi");
    2.11 +            SDL.loadLibrary("hidapi");
    2.12          } catch (Exception e) {
    2.13              Log.w(TAG, "Couldn't load hidapi: " + e.toString());
    2.14              return;
    2.15          }
    2.16 -	
    2.17 +
    2.18          HIDDeviceRegisterCallback(this);
    2.19  
    2.20          mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
     3.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDL.java	Thu Oct 04 15:23:42 2018 -0700
     3.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDL.java	Thu Oct 04 16:29:17 2018 -0700
     3.3 @@ -2,6 +2,8 @@
     3.4  
     3.5  import android.content.Context;
     3.6  
     3.7 +import java.lang.reflect.*;
     3.8 +
     3.9  /**
    3.10      SDL library initialization
    3.11  */
    3.12 @@ -33,5 +35,50 @@
    3.13          return mContext;
    3.14      }
    3.15  
    3.16 +    public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
    3.17 +
    3.18 +        if (libraryName == null) {
    3.19 +            throw new NullPointerException("No library name provided.");
    3.20 +        }
    3.21 +
    3.22 +        try {
    3.23 +            // Let's see if we have ReLinker available in the project.  This is necessary for 
    3.24 +            // some projects that have huge numbers of local libraries bundled, and thus may 
    3.25 +            // trip a bug in Android's native library loader which ReLinker works around.  (If
    3.26 +            // loadLibrary works properly, ReLinker will simply use the normal Android method
    3.27 +            // internally.)
    3.28 +            //
    3.29 +            // To use ReLinker, just add it as a dependency.  For more information, see 
    3.30 +            // https://github.com/KeepSafe/ReLinker for ReLinker's repository.
    3.31 +            //
    3.32 +            Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
    3.33 +            Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
    3.34 +            Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
    3.35 +            Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
    3.36 +
    3.37 +            // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if 
    3.38 +            // they've changed during updates.
    3.39 +            Method forceMethod = relinkClass.getDeclaredMethod("force");
    3.40 +            Object relinkInstance = forceMethod.invoke(null);
    3.41 +            Class relinkInstanceClass = relinkInstance.getClass();
    3.42 +
    3.43 +            // Actually load the library!
    3.44 +            Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
    3.45 +            loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
    3.46 +        }
    3.47 +        catch (final Exception e) {
    3.48 +            // Fall back
    3.49 +            try {
    3.50 +                System.loadLibrary(libraryName);
    3.51 +            }
    3.52 +            catch (final UnsatisfiedLinkError ule) {
    3.53 +                throw ule;
    3.54 +            }
    3.55 +            catch (final SecurityException se) {
    3.56 +                throw se;
    3.57 +            }
    3.58 +        }        
    3.59 +    }
    3.60 +
    3.61      protected static Context mContext;
    3.62  }
     4.1 --- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Thu Oct 04 15:23:42 2018 -0700
     4.2 +++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java	Thu Oct 04 16:29:17 2018 -0700
     4.3 @@ -154,7 +154,7 @@
     4.4      // Load the .so
     4.5      public void loadLibraries() {
     4.6         for (String lib : getLibraries()) {
     4.7 -          System.loadLibrary(lib);
     4.8 +          SDL.loadLibrary(lib);
     4.9         }
    4.10      }
    4.11