mirror of
https://github.com/YTVanced/VancedMicroG
synced 2024-12-03 08:17:26 +00:00
Adjust dynamite loader to support chimera modules with merged class loaders
This commit is contained in:
parent
e42f68497f
commit
5d50ae375f
4 changed files with 185 additions and 22 deletions
|
@ -3,8 +3,12 @@ package com.google.android.gms.dynamite;
|
||||||
import com.google.android.gms.dynamic.IObjectWrapper;
|
import com.google.android.gms.dynamic.IObjectWrapper;
|
||||||
|
|
||||||
interface IDynamiteLoader {
|
interface IDynamiteLoader {
|
||||||
int getModuleVersion(IObjectWrapper context, String moduleId) = 0;
|
int getModuleVersion(IObjectWrapper wrappedContext, String moduleId) = 0;
|
||||||
int getModuleVersion2(IObjectWrapper context, String moduleId, boolean updateConfigIfRequired) = 2;
|
int getModuleVersion2(IObjectWrapper wrappedContext, String moduleId, boolean updateConfigIfRequired) = 2;
|
||||||
|
int getModuleVersion2NoCrashUtils(IObjectWrapper wrappedContext, String moduleId, boolean updateConfigIfRequired) = 4;
|
||||||
|
|
||||||
IObjectWrapper createModuleContext(IObjectWrapper context, String moduleId, int minVersion) = 1;
|
IObjectWrapper createModuleContext(IObjectWrapper wrappedContext, String moduleId, int minVersion) = 1;
|
||||||
|
IObjectWrapper createModuleContextNoCrashUtils(IObjectWrapper wrappedContext, String moduleId, int minVersion) = 3;
|
||||||
|
|
||||||
|
int getIDynamiteLoaderVersion() = 5;
|
||||||
}
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.chimera.container;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
import android.content.pm.ApplicationInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
|
import org.microg.gms.common.Constants;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import dalvik.system.PathClassLoader;
|
||||||
|
|
||||||
|
public class DynamiteContext extends ContextWrapper {
|
||||||
|
private static final String TAG = "DynamiteContext";
|
||||||
|
private String moduleId;
|
||||||
|
private Context originalContext;
|
||||||
|
private Context gmsContext;
|
||||||
|
private DynamiteContext appContext;
|
||||||
|
|
||||||
|
public DynamiteContext(String moduleId, Context base, Context gmsContext, DynamiteContext appContext) {
|
||||||
|
super(base);
|
||||||
|
this.moduleId = moduleId;
|
||||||
|
this.originalContext = base;
|
||||||
|
this.gmsContext = gmsContext;
|
||||||
|
this.appContext = appContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassLoader getClassLoader() {
|
||||||
|
if (new DynamiteModuleInfo(moduleId).isMergeClassLoader()) {
|
||||||
|
StringBuilder nativeLoaderDirs = new StringBuilder(gmsContext.getApplicationInfo().nativeLibraryDir);
|
||||||
|
if (Build.VERSION.SDK_INT >= 23 && Process.is64Bit()) {
|
||||||
|
for (String abi : Build.SUPPORTED_64_BIT_ABIS) {
|
||||||
|
nativeLoaderDirs.append(File.pathSeparator).append(gmsContext.getApplicationInfo().sourceDir).append("!/lib/").append(abi);
|
||||||
|
}
|
||||||
|
} else if (Build.VERSION.SDK_INT >= 21) {
|
||||||
|
for (String abi : Build.SUPPORTED_32_BIT_ABIS) {
|
||||||
|
nativeLoaderDirs.append(File.pathSeparator).append(gmsContext.getApplicationInfo().sourceDir).append("!/lib/").append(abi);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nativeLoaderDirs.append(File.pathSeparator).append(gmsContext.getApplicationInfo().sourceDir).append("!/lib/").append(Build.CPU_ABI);
|
||||||
|
}
|
||||||
|
return new PathClassLoader(gmsContext.getApplicationInfo().sourceDir, nativeLoaderDirs.toString(), originalContext.getClassLoader());
|
||||||
|
} else {
|
||||||
|
return gmsContext.getClassLoader();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPackageName() {
|
||||||
|
return gmsContext.getPackageName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApplicationInfo getApplicationInfo() {
|
||||||
|
return gmsContext.getApplicationInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getApplicationContext() {
|
||||||
|
return appContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(24)
|
||||||
|
@Override
|
||||||
|
public Context createDeviceProtectedStorageContext() {
|
||||||
|
return new DynamiteContext(moduleId, originalContext.createDeviceProtectedStorageContext(), gmsContext.createDeviceProtectedStorageContext(), appContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DynamiteContext create(String moduleId, Context originalContext) {
|
||||||
|
try {
|
||||||
|
Context gmsContext = originalContext.createPackageContext(Constants.GMS_PACKAGE_NAME, new DynamiteModuleInfo(moduleId).getCreatePackageOptions());
|
||||||
|
Context originalAppContext = originalContext.getApplicationContext();
|
||||||
|
if (originalAppContext == null || originalAppContext == originalContext) {
|
||||||
|
return new DynamiteContext(moduleId, originalContext, gmsContext, null);
|
||||||
|
} else {
|
||||||
|
return new DynamiteContext(moduleId, originalContext, gmsContext, new DynamiteContext(moduleId, originalAppContext, gmsContext, null));
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,28 +35,41 @@ public class DynamiteLoaderImpl extends IDynamiteLoader.Stub {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IObjectWrapper createModuleContext(IObjectWrapper wrappedContext, String moduleId, int minVersion) throws RemoteException {
|
public IObjectWrapper createModuleContext(IObjectWrapper wrappedContext, String moduleId, int minVersion) throws RemoteException {
|
||||||
|
// We don't have crash utils, so just forward
|
||||||
|
return createModuleContextNoCrashUtils(wrappedContext, moduleId, minVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IObjectWrapper createModuleContextNoCrashUtils(IObjectWrapper wrappedContext, String moduleId, int minVersion) throws RemoteException {
|
||||||
Log.d(TAG, "createModuleContext for " + moduleId + " at version " + minVersion);
|
Log.d(TAG, "createModuleContext for " + moduleId + " at version " + minVersion);
|
||||||
|
final Context originalContext = (Context) ObjectWrapper.unwrap(wrappedContext);
|
||||||
|
return ObjectWrapper.wrap(DynamiteContext.create(moduleId, originalContext));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIDynamiteLoaderVersion() throws RemoteException {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModuleVersion(IObjectWrapper wrappedContext, String moduleId) throws RemoteException {
|
||||||
|
return getModuleVersion2(wrappedContext, moduleId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModuleVersion2(IObjectWrapper wrappedContext, String moduleId, boolean updateConfigIfRequired) throws RemoteException {
|
||||||
|
// We don't have crash utils, so just forward
|
||||||
|
return getModuleVersion2NoCrashUtils(wrappedContext, moduleId, updateConfigIfRequired);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getModuleVersion2NoCrashUtils(IObjectWrapper wrappedContext, String moduleId, boolean updateConfigIfRequired) throws RemoteException {
|
||||||
final Context context = (Context) ObjectWrapper.unwrap(wrappedContext);
|
final Context context = (Context) ObjectWrapper.unwrap(wrappedContext);
|
||||||
try {
|
if (context == null) {
|
||||||
return ObjectWrapper.wrap(new ContextWrapper(context.createPackageContext(Constants.GMS_PACKAGE_NAME, Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY)) {
|
Log.w(TAG, "Invalid client context");
|
||||||
@Override
|
return 0;
|
||||||
public Context getApplicationContext() {
|
|
||||||
return context;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
Log.w(TAG, "returning null instead", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getModuleVersion(IObjectWrapper context, String moduleId) throws RemoteException {
|
|
||||||
return getModuleVersion2(context, moduleId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getModuleVersion2(IObjectWrapper context, String moduleId, boolean updateConfigIfRequired) throws RemoteException {
|
|
||||||
try {
|
try {
|
||||||
return Class.forName("com.google.android.gms.dynamite.descriptors." + moduleId + ".ModuleDescriptor").getDeclaredField("MODULE_VERSION").getInt(null);
|
return Class.forName("com.google.android.gms.dynamite.descriptors." + moduleId + ".ModuleDescriptor").getDeclaredField("MODULE_VERSION").getInt(null);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2021, microG Project Team
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.android.gms.chimera.container;
|
||||||
|
|
||||||
|
import static android.content.Context.CONTEXT_IGNORE_SECURITY;
|
||||||
|
import static android.content.Context.CONTEXT_INCLUDE_CODE;
|
||||||
|
|
||||||
|
public class DynamiteModuleInfo {
|
||||||
|
private Class<?> descriptor;
|
||||||
|
private String moduleId;
|
||||||
|
|
||||||
|
public DynamiteModuleInfo(String moduleId) {
|
||||||
|
this.moduleId = moduleId;
|
||||||
|
try {
|
||||||
|
this.descriptor = Class.forName("com.google.android.gms.dynamite.descriptors." + moduleId + ".ModuleDescriptor");
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModuleId() {
|
||||||
|
return moduleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
try {
|
||||||
|
return descriptor.getDeclaredField("MODULE_VERSION").getInt(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCreatePackageOptions() {
|
||||||
|
try {
|
||||||
|
return descriptor.getDeclaredField("CREATE_PACKAGE_OPTIONS").getInt(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return CONTEXT_INCLUDE_CODE | CONTEXT_IGNORE_SECURITY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMergeClassLoader() {
|
||||||
|
try {
|
||||||
|
return descriptor.getDeclaredField("MERGE_CLASS_LOADER").getBoolean(null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue