Use shared namespace for bundled apps

This change adds support of shared namespaces when
creating classloader for bundled apps.

Bug: http://b/22548808
Bug: http://b/26165097
Change-Id: I4b4c89e68d83b57d4a9e462725d8b94b3562afef
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index 0e112fc..e329a4c 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -28,6 +28,7 @@
  */
 public class BaseDexClassLoader extends ClassLoader {
     private final DexPathList pathList;
+    private final boolean sharedNamespace;
 
     /**
      * Constructs an instance.
@@ -46,7 +47,7 @@
      */
     public BaseDexClassLoader(String dexPath, File optimizedDirectory,
             String librarySearchPath, ClassLoader parent) {
-        this(dexPath, optimizedDirectory, librarySearchPath, null, parent);
+        this(dexPath, optimizedDirectory, false, librarySearchPath, null, parent);
     }
 
     /**
@@ -57,6 +58,11 @@
      * defaults to {@code ":"} on Android
      * @param optimizedDirectory directory where optimized dex files
      * should be written; may be {@code null}
+     * @param isSharedNamespace whether this classloader should use the shared linker
+     * namespace. If the shared linker namespace is used, the classloader will have
+     * access to all native libraries loaded by the platform. This should be limited
+     * to the classloaders used by the bundled apps - bundled apps are part of the
+     * platform
      * @param librarySearchPath the list of directories containing native
      * libraries, delimited by {@code File.pathSeparator}; may be
      * {@code null}; directories in this list are used to search for
@@ -72,11 +78,12 @@
      *
      * @hide
      */
-    public BaseDexClassLoader(String dexPath, File optimizedDirectory,
+    public BaseDexClassLoader(String dexPath, File optimizedDirectory, boolean isSharedNamespace,
             String librarySearchPath, String libraryPermittedPath, ClassLoader parent) {
         super(parent);
         this.pathList = new DexPathList(this, dexPath, librarySearchPath,
                                         libraryPermittedPath, optimizedDirectory);
+        this.sharedNamespace = isSharedNamespace;
     }
 
     @Override
@@ -172,6 +179,13 @@
         return pathList.getLibraryPermittedPath();
     }
 
+    /**
+     * @hide
+     */
+    public boolean isSharedNamespace() {
+      return sharedNamespace;
+    }
+
     @Override public String toString() {
         return getClass().getName() + "[" + pathList + "]";
     }
diff --git a/dalvik/src/main/java/dalvik/system/DexClassLoader.java b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
index 4bbdbd8..3a584e8 100644
--- a/dalvik/src/main/java/dalvik/system/DexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/DexClassLoader.java
@@ -56,7 +56,7 @@
      */
     public DexClassLoader(String dexPath, String optimizedDirectory,
             String librarySearchPath, ClassLoader parent) {
-        super(dexPath, new File(optimizedDirectory), librarySearchPath, null, parent);
+        super(dexPath, new File(optimizedDirectory), false, librarySearchPath, null, parent);
     }
 
     /**
@@ -88,7 +88,7 @@
      */
     public DexClassLoader(String dexPath, String optimizedDirectory,
             String librarySearchPath, String libraryPermittedPath, ClassLoader parent) {
-        super(dexPath, new File(optimizedDirectory), librarySearchPath,
+        super(dexPath, new File(optimizedDirectory), false, librarySearchPath,
               libraryPermittedPath, parent);
     }
 }
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index 83b4366..5375935 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -35,7 +35,7 @@
      * @param parent the parent class loader
      */
     public PathClassLoader(String dexPath, ClassLoader parent) {
-        super(dexPath, null, null, null, parent);
+        super(dexPath, null, false, null, null, parent);
     }
 
     /**
@@ -63,7 +63,7 @@
      * This method will be deprecated in the next release
      */
     public PathClassLoader(String dexPath, String librarySearchPath, ClassLoader parent) {
-        super(dexPath, null, librarySearchPath, null, parent);
+        super(dexPath, null, false, librarySearchPath, null, parent);
     }
 
     /**
@@ -83,6 +83,11 @@
      * @param dexPath the list of jar/apk files containing classes and
      * resources, delimited by {@code File.pathSeparator}, which
      * defaults to {@code ":"} on Android
+     * @param isSharedNamespace whether this classloader should use the shared linker
+     * namespace. If the shared linker namespace is used, the classloader will have
+     * access to all native libraries loaded by the platform. This should be limited
+     * to the classloaders used by the bundled apps - bundled apps are part of the
+     * platform
      * @param librarySearchPath the list of directories containing native
      * libraries, delimited by {@code File.pathSeparator}; may be
      * {@code null}
@@ -95,8 +100,8 @@
      *
      * @hide
      */
-    public PathClassLoader(String dexPath, String librarySearchPath, String libraryPermittedPath,
-            ClassLoader parent) {
-        super(dexPath, null, librarySearchPath, libraryPermittedPath, parent);
+    public PathClassLoader(String dexPath, boolean isSharedNamespace, String librarySearchPath,
+            String libraryPermittedPath, ClassLoader parent) {
+        super(dexPath, null, isSharedNamespace, librarySearchPath, libraryPermittedPath, parent);
     }
 }
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index 8ed2ad0..bf5e4f4 100755
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -1034,21 +1034,24 @@
         // So, find out what the native library search path is for the ClassLoader in question...
         String librarySearchPath = null;
         String libraryPermittedPath = null;
+        boolean isSharedNamespace = false;
         if (loader != null && loader instanceof BaseDexClassLoader) {
             BaseDexClassLoader dexClassLoader = (BaseDexClassLoader) loader;
             librarySearchPath = dexClassLoader.getLdLibraryPath();
             libraryPermittedPath = dexClassLoader.getLibraryPermittedPath();
+            isSharedNamespace = dexClassLoader.isSharedNamespace();
         }
         // nativeLoad should be synchronized so there's only one LD_LIBRARY_PATH in use regardless
         // of how many ClassLoaders are in the system, but dalvik doesn't support synchronized
         // internal natives.
         synchronized (this) {
-            return nativeLoad(name, loader, librarySearchPath, libraryPermittedPath);
+            return nativeLoad(name, loader, isSharedNamespace,
+                              librarySearchPath, libraryPermittedPath);
         }
     }
 
     // TODO: should be synchronized, but dalvik doesn't support synchronized internal natives.
-    private static native String nativeLoad(String filename, ClassLoader loader,
+    private static native String nativeLoad(String filename, ClassLoader loader, boolean isBundled,
                                             String librarySearchPath, String libraryPermittedPath);
 
     /**
diff --git a/ojluni/src/main/native/Runtime.c b/ojluni/src/main/native/Runtime.c
index 1f7ee9e..dcf3614 100755
--- a/ojluni/src/main/native/Runtime.c
+++ b/ojluni/src/main/native/Runtime.c
@@ -77,9 +77,10 @@
 
 JNIEXPORT jstring JNICALL
 Runtime_nativeLoad(JNIEnv* env, jclass ignored, jstring javaFilename, jobject javaLoader,
-                   jstring javaLibrarySearchPath, jstring javaLibraryPermittedPath)
+                   jboolean isBundled, jstring javaLibrarySearchPath,
+                   jstring javaLibraryPermittedPath)
 {
-    return JVM_NativeLoad(env, javaFilename, javaLoader,
+    return JVM_NativeLoad(env, javaFilename, javaLoader, isBundled,
                           javaLibrarySearchPath, javaLibraryPermittedPath);
 }
 
@@ -90,7 +91,7 @@
   NATIVE_METHOD(Runtime, gc, "()V"),
   NATIVE_METHOD(Runtime, nativeExit, "(I)V"),
   NATIVE_METHOD(Runtime, nativeLoad,
-                "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;)"
+                "(Ljava/lang/String;Ljava/lang/ClassLoader;ZLjava/lang/String;Ljava/lang/String;)"
                     "Ljava/lang/String;"),
 };
 
diff --git a/ojluni/src/main/native/jvm.h b/ojluni/src/main/native/jvm.h
index 1a373c2..d0f5862 100644
--- a/ojluni/src/main/native/jvm.h
+++ b/ojluni/src/main/native/jvm.h
@@ -166,7 +166,8 @@
 JVM_ActiveProcessorCount(void);
 
 JNIEXPORT jstring JVM_NativeLoad(JNIEnv* env, jstring javaFilename, jobject javaLoader,
-                                 jstring javaLibrarySearchPath, jstring javaLibraryPermittedPath);
+                                 jboolean isBundled, jstring javaLibrarySearchPath,
+                                 jstring javaLibraryPermittedPath);
 
 JNIEXPORT void * JNICALL
 JVM_LoadLibrary(const char *name);