Skip to content

Commit

Permalink
add process type COMPLETE
Browse files Browse the repository at this point in the history
  • Loading branch information
ReginaldLiu committed Jun 26, 2018
1 parent bd54072 commit 161c2cf
Show file tree
Hide file tree
Showing 27 changed files with 2,198 additions and 158 deletions.
2 changes: 1 addition & 1 deletion PluginManager/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ android {
}

dependencies {
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:support-annotations:25.3.1'
compile project(':PluginApi')
}
1,682 changes: 1,682 additions & 0 deletions PluginManager/src/main/AndroidManifest.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ interface IPluginManager {
void onServiceCreated(in ServiceInfo stubInfo,in ServiceInfo targetInfo);
void onServiceDestory(in ServiceInfo stubInfo,in ServiceInfo targetInfo);
void onProviderCreated(in ProviderInfo stubInfo,in ProviderInfo targetInfo);

String getPluginProcessName(int pid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public class PluginConfigs {
*/
public static final int PROCESS_TYPE_DUAL = StubManager.PROCESS_TYPE_DUAL;

/**
* 完整进程模式: 所有插件都完全拥有全部的进程,进程名与插件声明的进程名称一致。(适合加载第三方独立apk)
*/
public static final int PROCESS_TYPE_COMPLETE = StubManager.PROCESS_TYPE_COMPLETE;

private int mProcessType = PROCESS_TYPE_INDEPENDENT;
private boolean mUseHostLoader = true;
private final Set<Signature> mSignatures = new HashSet<>();
Expand Down Expand Up @@ -102,6 +107,9 @@ public String toString() {
case PROCESS_TYPE_DUAL:
processType = "DUAL";
break;
case PROCESS_TYPE_COMPLETE:
processType = "COMPLETE";
break;
}
return String.format(" PluginConfig[ mProcessType = %s, mUseHostLoader = %b, " +
"mSignatureCheckEnabled = %b, mSignatures = %d ]",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
package com.reginald.pluginm.core;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.android.common.ActivityThreadCompat;
import com.reginald.pluginm.PluginInfo;
import com.reginald.pluginm.reflect.FieldUtils;
import com.reginald.pluginm.reflect.MethodUtils;
import com.reginald.pluginm.stub.PluginStubLocalActivityManager;
import com.reginald.pluginm.stub.Stubs;
import com.reginald.pluginm.utils.Logger;
import com.reginald.pluginm.utils.ProcessHelper;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityGroup;
Expand All @@ -12,23 +26,11 @@
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.UserHandle;
import android.view.ContextThemeWrapper;

import com.android.common.ActivityThreadCompat;
import com.reginald.pluginm.PluginInfo;
import com.reginald.pluginm.reflect.FieldUtils;
import com.reginald.pluginm.reflect.MethodUtils;
import com.reginald.pluginm.stub.PluginStubLocalActivityManager;
import com.reginald.pluginm.stub.Stubs;
import com.reginald.pluginm.utils.Logger;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* Created by lxy on 17-8-9.
*/
Expand All @@ -37,16 +39,20 @@ public class HostInstrumentation extends Instrumentation {

private static Class<?> sIAppTaskClazz;

private Instrumentation mBase;
private static Instrumentation sBase;

private static Instrumentation mBase;
private PluginManager mPluginManager;

private Intent mLastNewTargetIntent;
private WeakReference<Activity> mLastNewTargetActivity;

public HostInstrumentation(PluginManager pluginManager, Instrumentation base) {
this.mPluginManager = pluginManager;
this.mBase = base;
this.mBase = sBase != null ? sBase : base;
if (sBase == null) {
sBase = base;
}
}

public static Instrumentation install(Context hostContext) {
Expand Down Expand Up @@ -302,7 +308,7 @@ public Activity newActivity(ClassLoader cl, String className, Intent intent) thr
ActivityInfo activityInfo = intent.getParcelableExtra(PluginManager.EXTRA_INTENT_TARGET_ACTIVITYINFO);
Logger.d(TAG, "newActivity() target activityInfo = " + activityInfo);
if (activityInfo != null) {
PluginInfo pluginInfo = mPluginManager.loadPlugin(activityInfo.packageName);
PluginInfo pluginInfo = mPluginManager.loadPlugin(activityInfo);

if (pluginInfo != null) {
try {
Expand Down Expand Up @@ -408,7 +414,7 @@ public void callActivityOnCreate(Activity activity, Bundle icicle) {
try {
FieldUtils.writeField(activity, "mInstrumentation", this);
Logger.d(TAG, "callActivityOnCreate() replace mInstrumentation ok! ");
} catch (IllegalAccessException e) {
} catch (Exception e) {
Logger.e(TAG, "callActivityOnCreate() replace mInstrumentation error! ", e);
}

Expand Down Expand Up @@ -450,6 +456,14 @@ public void callActivityOnCreate(Activity activity, Bundle icicle) {
}

mBase.callActivityOnCreate(activity, icicle);

// ensure hook install
ProcessHelper.post(new Runnable() {
@Override
public void run() {
install(PluginManager.getInstance().getHostContext());
}
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.reginald.pluginm.core;

import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.reginald.pluginm.IPluginClient;
import com.reginald.pluginm.PluginInfo;
Expand All @@ -16,9 +15,10 @@
import com.reginald.pluginm.utils.ConfigUtils;
import com.reginald.pluginm.utils.Logger;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;

/**
* Created by lxy on 17-9-20.
Expand All @@ -30,6 +30,7 @@ public class PluginClientService extends IPluginClient.Stub {
private static volatile PluginClientService sInstance;

private Context mContext;
private PluginManager mPluginManager;
private final Map<String, IInvoker> mInvokerCacheMap = new HashMap<>();
private final Map<String, IBinder> mBinderCacheMap = new HashMap<>();

Expand All @@ -55,6 +56,7 @@ public static boolean attach(Context context) {
private PluginClientService(Context hostContext) {
Context appContext = hostContext.getApplicationContext();
mContext = appContext != null ? appContext : hostContext;
mPluginManager = PluginManager.getInstance();
}

@Override
Expand All @@ -63,20 +65,23 @@ public List<PluginInfo> getAllLoadedPlugins() throws RemoteException {
}

@Override
public InvokeResult invokePlugin(final String packageName, final String serviceName, final String methodName, String params, final InvokeCallback callback) throws RemoteException {
public InvokeResult invokePlugin(final String packageName, final String serviceName, final String methodName,
String params, final InvokeCallback callback) throws RemoteException {
IInvoker pluginInvoker = fetchPluginInvoker(packageName, serviceName);

if (pluginInvoker != null) {
IInvokeCallback iInvokeCallback = InvokeCallbackWrapper.build(callback);

PluginInfo pluginInfo = PluginManager.getInstance().getLoadedPluginInfo(packageName);
if (pluginInfo != null) {
IInvokeResult result = pluginInvoker.onInvoke(pluginInfo.baseContext, methodName, params, iInvokeCallback);
IInvokeResult result =
pluginInvoker.onInvoke(pluginInfo.baseContext, methodName, params, iInvokeCallback);
return InvokeResult.build(result);
}
}

Logger.w(TAG, String.format("invokePlugin() pkg = %s, service = %s, method = %s, params = %s, callback = %s, NOT found!",
Logger.w(TAG, String.format(
"invokePlugin() pkg = %s, service = %s, method = %s, params = %s, callback = %s, NOT found!",
packageName, serviceName, methodName, params, callback));

return new InvokeResult(IInvokeResult.RESULT_NOT_FOUND, null);
Expand All @@ -90,11 +95,12 @@ public IBinder fetchPluginService(String packageName, String serviceName) throws
private IBinder fetchPluginServiceBinder(String packageName, String serviceName) {
String key = keyForInvokerMap(packageName, serviceName);
if (key == null) {
Logger.w(TAG, String.format("fetchPluginServiceBinder() key is Null! for %s @ %s", serviceName, packageName));
Logger.w(TAG,
String.format("fetchPluginServiceBinder() key is Null! for %s @ %s", serviceName, packageName));
return null;
}

synchronized (mBinderCacheMap) {
synchronized(mBinderCacheMap) {
IBinder iBinder = mBinderCacheMap.get(key);
Logger.w(TAG, String.format("fetchPluginServiceBinder() cached binder = %s", iBinder));

Expand All @@ -105,14 +111,17 @@ private IBinder fetchPluginServiceBinder(String packageName, String serviceName)
IInvoker iPluginInvoker = fetchPluginInvoker(packageName, serviceName);

if (iPluginInvoker == null) {
Logger.w(TAG, String.format("fetchPluginServiceBinder() iPluginInvoker NOT found for %s @ %s", serviceName, packageName));
Logger.w(TAG,
String.format("fetchPluginServiceBinder() iPluginInvoker NOT found for %s @ %s", serviceName,
packageName));
return null;
}

PluginInfo pluginInfo = PluginManager.getInstance().getLoadedPluginInfo(packageName);

if (pluginInfo == null) {
Logger.w(TAG, String.format("fetchPluginServiceBinder() pluginInfo NOT found for %s @ %s", serviceName, packageName));
Logger.w(TAG, String.format("fetchPluginServiceBinder() pluginInfo NOT found for %s @ %s", serviceName,
packageName));
return null;
}

Expand All @@ -129,31 +138,35 @@ private IInvoker fetchPluginInvoker(String packageName, String serviceName) {
return null;
}

synchronized (mInvokerCacheMap) {
synchronized(mInvokerCacheMap) {
IInvoker pluginInvoker = mInvokerCacheMap.get(key);
Logger.w(TAG, String.format("fetchPluginInvoker() cached pluginInvoker = %s", pluginInvoker));

if (pluginInvoker != null) {
return pluginInvoker;
}

PluginInfo pluginInfo = PluginManager.getInstance().loadPlugin(packageName);

if (pluginInfo == null) {
Logger.w(TAG, String.format("fetchPluginInvoker() pluginInfo is Null! for %s @ %s", serviceName, packageName));
return null;
}

Logger.w(TAG, String.format("fetchPluginInvoker() pluginInfo = %s", pluginInfo));

try {
Map<String, String> serviceConfig = pluginInfo.pluginInvokerClassMap.get(serviceName);
PluginInfo installedPluginInfo = mPluginManager.getInstalledPluginInfo(packageName);
Map<String, String> serviceConfig = installedPluginInfo.pluginInvokerClassMap.get(serviceName);
if (serviceConfig == null) {
Logger.w(TAG, String.format("fetchPluginInvoker() pluginInvokerClassName NOT config! for %s @ %s",
serviceName, packageName));
return null;
}
String className = serviceConfig.get(ConfigUtils.KEY_INVOKER_CLASS);
String processName = serviceConfig.get(ConfigUtils.KEY_INVOKER_PROCESS);

PluginInfo pluginInfo = PluginManager.getInstance().loadPlugin(packageName, processName);

if (pluginInfo == null) {
Logger.w(TAG, String.format("fetchPluginInvoker() pluginInfo is Null! for %s @ %s", serviceName,
packageName));
return null;
}

Logger.w(TAG, String.format("fetchPluginInvoker() pluginInfo = %s", pluginInfo));

Class<?> invokerClazz = pluginInfo.classLoader.loadClass(className);
pluginInvoker = (IInvoker) invokerClazz.newInstance();
mInvokerCacheMap.put(key, pluginInvoker);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
package com.reginald.pluginm.core;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import com.android.common.ContextCompat;
import com.reginald.pluginm.IPluginManager;
import com.reginald.pluginm.PluginConfigs;
import com.reginald.pluginm.PluginInfo;
import com.reginald.pluginm.PluginM;
import com.reginald.pluginm.PluginNotFoundException;
import com.reginald.pluginm.comm.PluginLocalManager;
import com.reginald.pluginm.hook.IActivityManagerServiceHook;
import com.reginald.pluginm.parser.ApkParser;
import com.reginald.pluginm.pluginapi.IPluginLocalManager;
import com.reginald.pluginm.pluginapi.PluginHelper;
import com.reginald.pluginm.stub.PluginServiceConnection;
import com.reginald.pluginm.stub.PluginStubMainProvider;
import com.reginald.pluginm.stub.PluginStubMainService;
import com.reginald.pluginm.utils.BinderParcelable;
import com.reginald.pluginm.utils.Logger;
import com.reginald.pluginm.utils.ProcessHelper;
import com.reginald.pluginm.utils.ThreadUtils;

import android.app.Activity;
import android.app.Application;
import android.app.Instrumentation;
Expand Down Expand Up @@ -31,32 +58,6 @@
import android.util.Log;
import android.util.LogPrinter;
import android.util.Pair;

import com.android.common.ContextCompat;
import com.reginald.pluginm.IPluginManager;
import com.reginald.pluginm.PluginInfo;
import com.reginald.pluginm.PluginNotFoundException;
import com.reginald.pluginm.comm.PluginLocalManager;
import com.reginald.pluginm.hook.IActivityManagerServiceHook;
import com.reginald.pluginm.parser.ApkParser;
import com.reginald.pluginm.pluginapi.IPluginLocalManager;
import com.reginald.pluginm.pluginapi.PluginHelper;
import com.reginald.pluginm.stub.PluginServiceConnection;
import com.reginald.pluginm.stub.PluginStubMainProvider;
import com.reginald.pluginm.stub.PluginStubMainService;
import com.reginald.pluginm.utils.BinderParcelable;
import com.reginald.pluginm.utils.Logger;
import com.reginald.pluginm.utils.ProcessHelper;
import com.reginald.pluginm.utils.ThreadUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import dalvik.system.DexClassLoader;

/**
Expand Down Expand Up @@ -249,8 +250,12 @@ public Context getHostContext() {
return mContext;
}

public PluginInfo loadPlugin(String packageName) {
Logger.d(TAG, "loadPlugin() packageName = " + packageName);
public PluginInfo loadPlugin(ComponentInfo componentInfo) {
return loadPlugin(componentInfo.packageName, componentInfo.processName);
}

public PluginInfo loadPlugin(String packageName, String pluginProcessName) {
Logger.d(TAG, "loadPlugin() packageName = " + packageName + ", pluginProcessName = " + pluginProcessName);
try {
String pluginPackageName = packageName;
PluginInfo pluginInfo = null;
Expand Down Expand Up @@ -309,6 +314,10 @@ public PluginInfo loadPlugin(String packageName) {

mLoadedPluginMap.put(pluginPackageName, pluginInfo);
mLoadedClassLoaderMap.put(pluginPackageName, pluginClassLoader);

if (PluginM.getConfigs().getProcessType() == PluginConfigs.PROCESS_TYPE_COMPLETE) {
ProcessHelper.setArgV0(pluginProcessName);
}
}

if (!initPlugin(pluginInfo, mContext)) {
Expand Down Expand Up @@ -1029,4 +1038,16 @@ public boolean isPluginRunning(String pkgName) {
}
return false;
}

public String getPluginProcessName(int pid) {
IPluginManager service = ensureService(mService);
if (service != null) {
try {
return service.getPluginProcessName(pid);
} catch (RemoteException e) {
Logger.e(TAG, "getPluginProcessName() error!", e);
}
}
return null;
}
}
Loading

0 comments on commit 161c2cf

Please sign in to comment.