[RenderScript] Load from the full path of librsjni and libRSSupport.

  - For API 9+ load from the full path of librsjni, libRSSupport.
  - Enable logging of critical error.
  - Log the version of both JAVA and JNI.

Bug: 25226912
Change-Id: I357398634ec3bfd70c71e005241c5a66650bdba6
(cherry picked from commit 8b03eca305a4019ef712afa3a8deb1d348463e70)
diff --git a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
index 5dcb50b..34e9dd8 100644
--- a/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
+++ b/v8/renderscript/java/src/android/support/v8/renderscript/RenderScript.java
@@ -49,6 +49,7 @@
     @SuppressWarnings({"UnusedDeclaration", "deprecation"})
     static final boolean LOG_ENABLED = false;
     static final int SUPPORT_LIB_API = 23;
+    static final int SUPPORT_LIB_VERSION = 2301;
 
     static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
     private boolean mIsProcessContext = false;
@@ -97,7 +98,7 @@
     static Object lock = new Object();
 
     // Non-threadsafe functions.
-    native boolean nLoadSO(boolean useNative, int deviceApi);
+    native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
     native boolean nLoadIOSO();
     native long nDeviceCreate();
     native void nDeviceDestroy(long dev);
@@ -749,7 +750,7 @@
                     Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
                     throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
                 }
-                if (!nIncLoadSO(SUPPORT_LIB_API)) {
+                if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
                     throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
                 }
                 mIncLoaded = true;
@@ -945,7 +946,7 @@
 
 // Additional Entry points For inc libRSSupport
 
-    native boolean nIncLoadSO(int deviceApi);
+    native boolean nIncLoadSO(int deviceApi, String libPath);
     native long nIncDeviceCreate();
     native void nIncDeviceDestroy(long dev);
     // Methods below are wrapped to protect the non-threadsafe
@@ -1293,7 +1294,10 @@
         mContextType = ContextType.NORMAL;
         if (ctx != null) {
             mApplicationContext = ctx.getApplicationContext();
-            mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
+            // Only set mNativeLibDir for API 9+.
+            if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.FROYO) {
+                mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
+            }
         }
         mIncDev = 0;
         mIncCon = 0;
@@ -1339,12 +1343,18 @@
                     sUseGCHooks = false;
                 }
                 try {
-                    System.loadLibrary("rsjni");
+                    // For API 9+, always use the absolute path of librsjni.so
+                    // Bug: 25226912
+                    if (rs.mNativeLibDir != null) {
+                        System.load(rs.mNativeLibDir + "/librsjni.so");
+                    } else {
+                        System.loadLibrary("rsjni");
+                    }
                     sInitialized = true;
                     sPointerSize = rsnSystemGetPointerSize();
                 } catch (UnsatisfiedLinkError e) {
                     Log.e(LOG_TAG, "Error loading RS jni library: " + e);
-                    throw new RSRuntimeException("Error loading RS jni library: " + e);
+                    throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
                 }
             }
         }
@@ -1364,19 +1374,31 @@
             // If the device API is higher than target API level, init dispatch table based on device API.
             dispatchAPI = android.os.Build.VERSION.SDK_INT;
         }
-        if (!rs.nLoadSO(useNative, dispatchAPI)) {
+
+        String rssupportPath = null;
+        // For API 9+, always use the absolute path of libRSSupport.so
+        // Bug: 25226912
+        if (rs.mNativeLibDir != null) {
+            rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
+        }
+        if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
             if (useNative) {
                 android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
                 useNative = false;
             }
             try {
-                System.loadLibrary("RSSupport");
+                if (rs.mNativeLibDir != null) {
+                    System.load(rssupportPath);
+                } else {
+                    System.loadLibrary("RSSupport");
+                }
             } catch (UnsatisfiedLinkError e) {
-                Log.e(LOG_TAG, "Error loading RS Compat library: " + e);
-                throw new RSRuntimeException("Error loading RS Compat library: " + e);
+                Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
+                throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
             }
-            if (!rs.nLoadSO(false, dispatchAPI)) {
-                throw new RSRuntimeException("Error loading libRSSupport library");
+            if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
+                Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
+                throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
             }
         }
 
diff --git a/v8/renderscript/jni/Android.mk b/v8/renderscript/jni/Android.mk
index d2af4a9..72f8720 100644
--- a/v8/renderscript/jni/Android.mk
+++ b/v8/renderscript/jni/Android.mk
@@ -50,6 +50,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_REQUIRED_MODULES := libRSSupport
 
-LOCAL_LDFLAGS += -ldl
+LOCAL_LDFLAGS += -ldl -llog
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/v8/renderscript/jni/android_renderscript_RenderScript.cpp b/v8/renderscript/jni/android_renderscript_RenderScript.cpp
index 32243fc..976b60e 100644
--- a/v8/renderscript/jni/android_renderscript_RenderScript.cpp
+++ b/v8/renderscript/jni/android_renderscript_RenderScript.cpp
@@ -30,6 +30,8 @@
 
 //#define LOG_API ALOG
 #define LOG_API(...)
+#define LOG_ERR(...) __android_log_print(ANDROID_LOG_ERROR, "RenderScript JNI", __VA_ARGS__);
+#define RS_JNI_VERSION 2301
 
 #define NELEM(m) (sizeof(m) / sizeof((m)[0]))
 
@@ -269,23 +271,31 @@
 // Incremental Support lib
 static dispatchTable dispatchTabInc;
 
-static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi) {
+static jboolean nLoadSO(JNIEnv *_env, jobject _this, jboolean useNative, jint targetApi, jstring libPath) {
     void* handle = NULL;
     if (useNative) {
         handle = dlopen("libRS.so", RTLD_LAZY | RTLD_LOCAL);
     } else {
-        handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
+        // For API 9+, dlopen the full path of libRSSupport.
+        if (libPath != NULL) {
+            const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE);
+            handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL);
+            _env->ReleaseStringUTFChars(libPath, libPathJni);
+        } else {
+            handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
+        }
     }
     if (handle == NULL) {
-        LOG_API("couldn't dlopen %s, %s", filename, dlerror());
+        LOG_ERR("couldn't dlopen %s; librsjni version: %d", dlerror(), RS_JNI_VERSION);
         return false;
     }
 
     if (loadSymbols(handle, dispatchTab, targetApi) == false) {
-        LOG_API("%s init failed!", filename);
+        LOG_ERR("Dispatch table init failed! librsjni version: %d", RS_JNI_VERSION);
+        dlclose(handle);
         return false;
     }
-    LOG_API("Successfully loaded %s", filename);
+    LOG_API("Successfully loaded runtime");
     return true;
 }
 
@@ -294,11 +304,11 @@
     void* handleIO = NULL;
     handleIO = dlopen("libRSSupportIO.so", RTLD_LAZY | RTLD_LOCAL);
     if (handleIO == NULL) {
-        LOG_API("Couldn't load libRSSupportIO.so");
+        LOG_ERR("Couldn't load libRSSupportIO.so, librsjni version: %d", RS_JNI_VERSION);
         return false;
     }
     if (loadIOSuppSyms(handleIO, ioDispatch) == false) {
-        LOG_API("libRSSupportIO init failed!");
+        LOG_ERR("libRSSupportIO init failed! librsjni version: %d", RS_JNI_VERSION);
         return false;
     }
     return true;
@@ -367,26 +377,26 @@
   RsScriptFieldID* depFieldIDs;
 
   if (fieldIDs_length != values_length || values_length != sizes_length) {
-      LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
+      LOG_ERR("Unmatched field IDs, values, and sizes in closure creation.");
       goto exit;
   }
 
   numValues = (size_t)fieldIDs_length;
 
   if (depClosures_length != depFieldIDs_length) {
-      LOG_API("Unmatched closures and field IDs for dependencies in closure creation.");
+      LOG_ERR("Unmatched closures and field IDs for dependencies in closure creation.");
       goto exit;
   }
 
   numDependencies = (size_t)depClosures_length;
 
   if (numDependencies > numValues) {
-      LOG_API("Unexpected number of dependencies in closure creation");
+      LOG_ERR("Unexpected number of dependencies in closure creation");
       goto exit;
   }
 
   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
-      LOG_API("Too many arguments or globals in closure creation");
+      LOG_ERR("Too many arguments or globals in closure creation");
       goto exit;
   }
 
@@ -464,14 +474,14 @@
   uintptr_t* values;
 
   if (fieldIDs_length != values_length || values_length != sizes_length) {
-      LOG_API("Unmatched field IDs, values, and sizes in closure creation.");
+      LOG_ERR("Unmatched field IDs, values, and sizes in closure creation.");
       goto exit;
   }
 
   numValues = (size_t) fieldIDs_length;
 
   if (numValues > RS_CLOSURE_MAX_NUMBER_ARGS_AND_BINDINGS) {
-      LOG_API("Too many arguments or globals in closure creation");
+      LOG_ERR("Too many arguments or globals in closure creation");
       goto exit;
   }
 
@@ -536,7 +546,7 @@
   RsClosure* closures;
 
   if (numClosures > (jsize) RS_SCRIPT_GROUP_MAX_NUMBER_CLOSURES) {
-    LOG_API("Too many closures in script group");
+    LOG_ERR("Too many closures in script group");
     goto exit;
   }
 
@@ -1627,6 +1637,7 @@
     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
 }
 
+
 // -----------------------------------
 
 static jlong
@@ -1831,16 +1842,25 @@
 
 // ---------------------------------------------------------------------------
 // For Incremental Intrinsic Support
-static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi) {
+static jboolean nIncLoadSO(JNIEnv *_env, jobject _this, jint deviceApi, jstring libPath) {
     void* handle = NULL;
-    handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
+    // For API 9+, dlopen the full path of libRSSupport.
+    if (libPath != NULL) {
+        const char * libPathJni = _env->GetStringUTFChars(libPath, JNI_FALSE);
+        handle = dlopen(libPathJni, RTLD_LAZY | RTLD_LOCAL);
+        _env->ReleaseStringUTFChars(libPath, libPathJni);
+    } else {
+        handle = dlopen("libRSSupport.so", RTLD_LAZY | RTLD_LOCAL);
+    }
+
     if (handle == NULL) {
-        LOG_API("couldn't dlopen %s, %s", filename, dlerror());
+        LOG_ERR("couldn't dlopen %s;  librsjni version: %d", dlerror(), RS_JNI_VERSION);
         return false;
     }
 
     if (loadSymbols(handle, dispatchTabInc, deviceApi) == false) {
-        LOG_API("%s init failed!", filename);
+        LOG_ERR("Dispatch Table init failed! librsjni version: %d", RS_JNI_VERSION);
+        dlclose(handle);
         return false;
     }
     LOG_API("Successfully loaded %s", filename);
@@ -1946,7 +1966,7 @@
 static const char *classPathName = "android/support/v8/renderscript/RenderScript";
 
 static JNINativeMethod methods[] = {
-{"nLoadSO",                        "(ZI)Z",                                   (bool*)nLoadSO },
+{"nLoadSO",                        "(ZILjava/lang/String;)Z",                 (bool*)nLoadSO },
 {"nLoadIOSO",                      "()Z",                                     (bool*)nLoadIOSO },
 {"nDeviceCreate",                  "()J",                                     (void*)nDeviceCreate },
 {"nDeviceDestroy",                 "(J)V",                                    (void*)nDeviceDestroy },
@@ -2044,7 +2064,7 @@
 {"rsnSystemGetPointerSize",          "()I",                                   (void*)nSystemGetPointerSize },
 
 // Entry points for Inc libRSSupport
-{"nIncLoadSO",                       "(I)Z",                                  (bool*)nIncLoadSO },
+{"nIncLoadSO",                       "(ILjava/lang/String;)Z",                (bool*)nIncLoadSO },
 {"nIncDeviceCreate",                 "()J",                                   (void*)nIncDeviceCreate },
 {"nIncDeviceDestroy",                "(J)V",                                  (void*)nIncDeviceDestroy },
 {"rsnIncContextCreate",              "(JIII)J",                               (void*)nIncContextCreate },