diff --git a/play-services-maps/core/mapbox/src/main/java/com/google/android/gms/maps/internal/CreatorImpl.java b/play-services-maps/core/mapbox/src/main/java/com/google/android/gms/maps/internal/CreatorImpl.java index 0041f0638b..c18d24d110 100644 --- a/play-services-maps/core/mapbox/src/main/java/com/google/android/gms/maps/internal/CreatorImpl.java +++ b/play-services-maps/core/mapbox/src/main/java/com/google/android/gms/maps/internal/CreatorImpl.java @@ -29,6 +29,7 @@ import com.google.android.gms.maps.GoogleMapOptions; import com.google.android.gms.maps.StreetViewPanoramaOptions; import com.google.android.gms.maps.model.internal.IBitmapDescriptorFactoryDelegate; +import com.mapbox.mapboxsdk.LibraryLoader; import org.microg.gms.maps.mapbox.CameraUpdateFactoryImpl; import org.microg.gms.maps.mapbox.MapFragmentImpl; @@ -36,6 +37,8 @@ import org.microg.gms.maps.mapbox.StreetViewPanoramaFragmentImpl; import org.microg.gms.maps.mapbox.StreetViewPanoramaViewImpl; import org.microg.gms.maps.mapbox.model.BitmapDescriptorFactoryImpl; +import org.microg.gms.maps.mapbox.utils.MapContext; +import org.microg.gms.maps.mapbox.utils.MultiArchLoader; @Keep public class CreatorImpl extends ICreator.Stub { @@ -68,8 +71,13 @@ public IBitmapDescriptorFactoryDelegate newBitmapDescriptorFactoryDelegate() { @Override public void initV2(IObjectWrapper resources, int flags) { - BitmapDescriptorFactoryImpl.INSTANCE.initialize(ObjectWrapper.unwrapTyped(resources, Resources.class), null); - //ResourcesContainer.set((Resources) ObjectWrapper.unwrap(resources)); + Resources mapResources = ObjectWrapper.unwrapTyped(resources, Resources.class); + ClassLoader moduleClassLoader = CreatorImpl.class.getClassLoader(); + if (moduleClassLoader == null) { + throw new IllegalStateException("Mapbox backend class loader is not available"); + } + BitmapDescriptorFactoryImpl.INSTANCE.initialize(mapResources, null); + LibraryLoader.setLibraryLoader(new MultiArchLoader(moduleClassLoader)); Log.d(TAG, "initV2 " + flags); } diff --git a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt index e542fb6a53..c09d3d3fbf 100644 --- a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt +++ b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/GoogleMap.kt @@ -36,7 +36,6 @@ import com.google.android.gms.maps.internal.* import com.google.android.gms.maps.model.* import com.google.android.gms.maps.model.CircleOptions import com.google.android.gms.maps.model.internal.* -import com.mapbox.mapboxsdk.LibraryLoader import com.mapbox.mapboxsdk.Mapbox import com.mapbox.mapboxsdk.R import com.mapbox.mapboxsdk.camera.CameraUpdate @@ -60,7 +59,6 @@ import com.mapbox.mapboxsdk.camera.CameraUpdateFactory import com.mapbox.mapboxsdk.location.engine.* import com.mapbox.mapboxsdk.maps.OnMapReadyCallback import org.microg.gms.maps.mapbox.model.* -import org.microg.gms.maps.mapbox.utils.MultiArchLoader import org.microg.gms.maps.mapbox.utils.toGms import org.microg.gms.maps.mapbox.utils.toMapbox import java.util.concurrent.atomic.AtomicBoolean @@ -130,7 +128,6 @@ class GoogleMapImpl(context: Context, var options: GoogleMapOptions) : AbstractG init { BitmapDescriptorFactoryImpl.initialize(mapContext.resources, context.resources) - LibraryLoader.setLibraryLoader(MultiArchLoader(mapContext, context)) runOnMainLooper { Mapbox.getInstance(mapContext, BuildConfig.MAPBOX_KEY, WellKnownTileServer.Mapbox) } diff --git a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt index f889239647..c47c92c721 100644 --- a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt +++ b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MapContext.kt @@ -24,7 +24,7 @@ import android.view.LayoutInflater import org.microg.gms.common.Constants import java.io.File -class MapContext(private val context: Context) : ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY)) { +class MapContext(private val context: Context) : ContextWrapper(createModuleContext(context)) { private var layoutInflater: LayoutInflater? = null private val appContext: Context get() = context.applicationContext ?: context @@ -76,6 +76,10 @@ class MapContext(private val context: Context) : ContextWrapper(context.createPa } companion object { + private fun createModuleContext(context: Context): Context { + return context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY) + } + val TAG = "GmsMapContext" } } diff --git a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MultiArchLoader.kt b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MultiArchLoader.kt index 5a37a6d83c..e352879f6a 100644 --- a/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MultiArchLoader.kt +++ b/play-services-maps/core/mapbox/src/main/kotlin/org/microg/gms/maps/mapbox/utils/MultiArchLoader.kt @@ -17,45 +17,17 @@ package org.microg.gms.maps.mapbox.utils import android.annotation.SuppressLint -import android.content.Context -import android.content.pm.ApplicationInfo import android.util.Log import com.mapbox.mapboxsdk.LibraryLoader -import org.microg.gms.common.Constants -import org.microg.gms.common.PackageUtils -import java.io.* -import java.util.zip.ZipFile +import dalvik.system.BaseDexClassLoader -class MultiArchLoader(private val mapContext: Context, private val appContext: Context) : LibraryLoader() { +class MultiArchLoader(private val moduleClassLoader: ClassLoader) : LibraryLoader() { @SuppressLint("UnsafeDynamicallyLoadedCode") override fun load(name: String) { try { - val otherAppInfo = mapContext.packageManager.getApplicationInfo(appContext.packageName, 0) - var primaryCpuAbi = ApplicationInfo::class.java.getField("primaryCpuAbi").get(otherAppInfo) as String? - if (primaryCpuAbi == "armeabi") { - primaryCpuAbi = "armeabi-v7a" - } - if (primaryCpuAbi != null) { - val path = "lib/$primaryCpuAbi/lib$name.so" - val cacheFile = File("${appContext.cacheDir.absolutePath}/.gmscore/$path") - cacheFile.parentFile?.mkdirs() - val cacheFileStamp = File("${appContext.cacheDir.absolutePath}/.gmscore/$path.stamp") - val cacheVersion = kotlin.runCatching { cacheFileStamp.readText() }.getOrNull() - // TODO: Use better version indicator - val mapVersion = PackageUtils.versionName(mapContext, Constants.GMS_PACKAGE_NAME) - val apkFile = File(mapContext.packageCodePath) - if (!cacheFile.exists() || cacheVersion == null || cacheVersion != mapVersion) { - val zipFile = ZipFile(apkFile) - val entry = zipFile.getEntry(path) - if (entry != null) { - copyInputStream(zipFile.getInputStream(entry), FileOutputStream(cacheFile)) - } else { - Log.d(TAG, "Can't load native library: $path does not exist in $apkFile") - } - cacheFileStamp.writeText(mapVersion.toString()) - } - Log.d(TAG, "Loading $name from ${cacheFile.getPath()}") - System.load(cacheFile.absolutePath) + findLibrary(name)?.let { path -> + Log.d(TAG, "Loading $name from $path") + System.load(path) return } } catch (e: Exception) { @@ -65,17 +37,8 @@ class MultiArchLoader(private val mapContext: Context, private val appContext: C System.loadLibrary(name) } - @Throws(IOException::class) - private fun copyInputStream(inp: InputStream, out: OutputStream) { - val buffer = ByteArray(1024) - var len: Int = inp.read(buffer) - while (len >= 0) { - out.write(buffer, 0, len) - len = inp.read(buffer) - } - - inp.close() - out.close() + private fun findLibrary(name: String): String? { + return (moduleClassLoader as? BaseDexClassLoader)?.findLibrary(name) } companion object {