1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import org.jni_zero.CalledByNative; 8 9 import java.util.Map; 10 11 /** This class provides JNI-related methods to the native library. */ 12 public class JNIUtils { 13 private static final String TAG = "JNIUtils"; 14 private static ClassLoader sJniClassLoader; 15 16 /** 17 * Returns a ClassLoader which can load Java classes from the specified split. 18 * 19 * @param splitName Name of the split, or empty string for the base split. 20 */ 21 @CalledByNative getSplitClassLoader(String splitName)22 private static ClassLoader getSplitClassLoader(String splitName) { 23 if (!splitName.isEmpty()) { 24 boolean isInstalled = BundleUtils.isIsolatedSplitInstalled(splitName); 25 Log.i(TAG, "Init JNI Classloader for %s. isInstalled=%b", splitName, isInstalled); 26 27 if (isInstalled) { 28 return BundleUtils.getOrCreateSplitClassLoader(splitName); 29 } else { 30 // Split was installed by PlayCore in "compat" mode, meaning that our base module's 31 // ClassLoader was patched to add the splits' dex file to it. 32 // This should never happen on Android T+, where PlayCore is configured to fully 33 // install splits from the get-go, but can still sometimes happen if play store 34 // is very out of date. 35 } 36 } 37 return sJniClassLoader != null ? sJniClassLoader : JNIUtils.class.getClassLoader(); 38 } 39 40 /** 41 * Sets the ClassLoader to be used for loading Java classes from native. 42 * 43 * @param classLoader the ClassLoader to use. 44 */ setClassLoader(ClassLoader classLoader)45 public static void setClassLoader(ClassLoader classLoader) { 46 sJniClassLoader = classLoader; 47 } 48 49 /** Helper to convert from java maps to two arrays for JNI. */ splitMap(Map<K, V> map, K[] outKeys, V[] outValues)50 public static <K, V> void splitMap(Map<K, V> map, K[] outKeys, V[] outValues) { 51 assert map.size() == outKeys.length; 52 assert outValues.length == outKeys.length; 53 54 int i = 0; 55 for (Map.Entry<K, V> entry : map.entrySet()) { 56 outKeys[i] = entry.getKey(); 57 outValues[i] = entry.getValue(); 58 i++; 59 } 60 } 61 } 62