提交 a76beb3b 编写于 作者: S superq_sky

Optimized some code extensibility.

上级 254c9aac
......@@ -48,6 +48,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
......@@ -95,13 +96,13 @@ public class PluginManager {
}
private void prepare() {
this.hookInstrumentationAndHandler();
this.hookSystemServices();
mComponentsHandler = createComponentsHandler();
hookInstrumentationAndHandler();
hookSystemServices();
hookDataBindingUtil();
}
public void init() {
mComponentsHandler = new ComponentsHandler(this);
RunUtil.getThreadPool().execute(new Runnable() {
@Override
public void run() {
......@@ -110,10 +111,26 @@ public class PluginManager {
});
}
private void doInWorkThread() {
protected void doInWorkThread() {
}
private void hookDataBindingUtil() {
protected ComponentsHandler createComponentsHandler() {
return new ComponentsHandler(this);
}
protected VAInstrumentation createInstrumentation(Instrumentation origin) throws Exception {
return new VAInstrumentation(this, origin);
}
protected ActivityManagerProxy createActivityManagerProxy(IActivityManager origin) throws Exception {
return new ActivityManagerProxy(this, origin);
}
protected LoadedPlugin createLoadedPlugin(File apk) throws Exception {
return new LoadedPlugin(this, this.mContext, apk);
}
protected void hookDataBindingUtil() {
Reflector.QuietReflector reflector = Reflector.QuietReflector.on("android.databinding.DataBindingUtil").field("sMapper");
Object old = reflector.get();
if (old != null) {
......@@ -139,7 +156,7 @@ public class PluginManager {
/**
* hookSystemServices, but need to compatible with Android O in future.
*/
private void hookSystemServices() {
protected void hookSystemServices() {
try {
Singleton<IActivityManager> defaultSingleton;
......@@ -148,7 +165,9 @@ public class PluginManager {
} else {
defaultSingleton = Reflector.on(ActivityManagerNative.class).field("gDefault").get();
}
IActivityManager activityManagerProxy = ActivityManagerProxy.newInstance(this, defaultSingleton.get());
IActivityManager origin = defaultSingleton.get();
IActivityManager activityManagerProxy = (IActivityManager) Proxy.newProxyInstance(mContext.getClassLoader(), new Class[] { IActivityManager.class },
createActivityManagerProxy(origin));
// Hook IActivityManager from ActivityManagerNative
Reflector.with(defaultSingleton).field("mInstance").set(activityManagerProxy);
......@@ -160,8 +179,8 @@ public class PluginManager {
e.printStackTrace();
}
}
private void hookInstrumentationAndHandler() {
protected void hookInstrumentationAndHandler() {
try {
ActivityThread activityThread = ActivityThread.currentActivityThread();
Instrumentation baseInstrumentation = activityThread.getInstrumentation();
......@@ -170,7 +189,7 @@ public class PluginManager {
System.exit(0);
}
final VAInstrumentation instrumentation = new VAInstrumentation(this, baseInstrumentation);
final VAInstrumentation instrumentation = createInstrumentation(baseInstrumentation);
Reflector.with(activityThread).field("mInstrumentation").set(instrumentation);
Handler mainHandler = Reflector.with(activityThread).method("getHandler").call();
......@@ -181,7 +200,7 @@ public class PluginManager {
}
}
private void hookIContentProviderAsNeeded() {
protected void hookIContentProviderAsNeeded() {
Uri uri = Uri.parse(PluginContentResolver.getUri(mContext));
mContext.getContentResolver().call(uri, "wakeup", null, null);
try {
......@@ -237,7 +256,7 @@ public class PluginManager {
in.close();
}
LoadedPlugin plugin = LoadedPlugin.create(this, this.mContext, apk);
LoadedPlugin plugin = createLoadedPlugin(apk);
if (null != plugin) {
this.mPlugins.put(plugin.getPackageName(), plugin);
synchronized (mCallbacks) {
......
......@@ -51,10 +51,6 @@ public class ActivityManagerProxy implements InvocationHandler {
public static final int INTENT_SENDER_ACTIVITY_RESULT = 3;
public static final int INTENT_SENDER_SERVICE = 4;
public static IActivityManager newInstance(PluginManager pluginManager, IActivityManager activityManager) {
return (IActivityManager) Proxy.newProxyInstance(activityManager.getClass().getClassLoader(), new Class[] { IActivityManager.class }, new ActivityManagerProxy(pluginManager, activityManager));
}
private PluginManager mPluginManager;
private IActivityManager mActivityManager;
......@@ -135,7 +131,7 @@ public class ActivityManagerProxy implements InvocationHandler {
}
private Object startService(Object proxy, Method method, Object[] args) throws Throwable {
protected Object startService(Object proxy, Method method, Object[] args) throws Throwable {
IApplicationThread appThread = (IApplicationThread) args[0];
Intent target = (Intent) args[1];
ResolveInfo resolveInfo = this.mPluginManager.resolveService(target, 0);
......@@ -147,7 +143,7 @@ public class ActivityManagerProxy implements InvocationHandler {
return startDelegateServiceForTarget(target, resolveInfo.serviceInfo, null, RemoteService.EXTRA_COMMAND_START_SERVICE);
}
private Object stopService(Object proxy, Method method, Object[] args) throws Throwable {
protected Object stopService(Object proxy, Method method, Object[] args) throws Throwable {
Intent target = (Intent) args[1];
ResolveInfo resolveInfo = this.mPluginManager.resolveService(target, 0);
if (null == resolveInfo || null == resolveInfo.serviceInfo) {
......@@ -159,7 +155,7 @@ public class ActivityManagerProxy implements InvocationHandler {
return 1;
}
private Object stopServiceToken(Object proxy, Method method, Object[] args) throws Throwable {
protected Object stopServiceToken(Object proxy, Method method, Object[] args) throws Throwable {
ComponentName component = (ComponentName) args[0];
Intent target = new Intent().setComponent(component);
ResolveInfo resolveInfo = this.mPluginManager.resolveService(target, 0);
......@@ -172,7 +168,7 @@ public class ActivityManagerProxy implements InvocationHandler {
return true;
}
private Object bindService(Object proxy, Method method, Object[] args) throws Throwable {
protected Object bindService(Object proxy, Method method, Object[] args) throws Throwable {
Intent target = (Intent) args[2];
ResolveInfo resolveInfo = this.mPluginManager.resolveService(target, 0);
if (null == resolveInfo || null == resolveInfo.serviceInfo) {
......@@ -187,7 +183,7 @@ public class ActivityManagerProxy implements InvocationHandler {
return 1;
}
private Object unbindService(Object proxy, Method method, Object[] args) throws Throwable {
protected Object unbindService(Object proxy, Method method, Object[] args) throws Throwable {
IBinder iServiceConnection = (IBinder)args[0];
Intent target = mPluginManager.getComponentsHandler().forgetIServiceConnection(iServiceConnection);
if (target == null) {
......@@ -200,12 +196,12 @@ public class ActivityManagerProxy implements InvocationHandler {
return true;
}
private ComponentName startDelegateServiceForTarget(Intent target, ServiceInfo serviceInfo, Bundle extras, int command) {
protected ComponentName startDelegateServiceForTarget(Intent target, ServiceInfo serviceInfo, Bundle extras, int command) {
Intent wrapperIntent = wrapperTargetIntent(target, serviceInfo, extras, command);
return mPluginManager.getHostContext().startService(wrapperIntent);
}
private Intent wrapperTargetIntent(Intent target, ServiceInfo serviceInfo, Bundle extras, int command) {
protected Intent wrapperTargetIntent(Intent target, ServiceInfo serviceInfo, Bundle extras, int command) {
// fill in service with ComponentName
target.setComponent(new ComponentName(serviceInfo.packageName, serviceInfo.name));
String pluginLocation = mPluginManager.getLoadedPlugin(target.getComponent()).getLocation();
......@@ -225,7 +221,7 @@ public class ActivityManagerProxy implements InvocationHandler {
return intent;
}
private void getIntentSender(Method method, Object[] args) {
protected void getIntentSender(Method method, Object[] args) {
String hostPackageName = mPluginManager.getHostContext().getPackageName();
args[1] = hostPackageName;
......@@ -246,7 +242,7 @@ public class ActivityManagerProxy implements InvocationHandler {
}
}
private void overridePendingTransition(Method method, Object[] args) {
protected void overridePendingTransition(Method method, Object[] args) {
String hostPackageName = mPluginManager.getHostContext().getPackageName();
args[1] = hostPackageName;
}
......
......@@ -78,11 +78,7 @@ public final class LoadedPlugin {
public static final String TAG = "LoadedPlugin";
public static LoadedPlugin create(PluginManager pluginManager, Context host, File apk) throws Exception {
return new LoadedPlugin(pluginManager, host, apk);
}
private static ClassLoader createClassLoader(Context context, File apk, File libsDir, ClassLoader parent) {
protected ClassLoader createClassLoader(Context context, File apk, File libsDir, ClassLoader parent) {
File dexOutputDir = context.getDir(Constants.OPTIMIZE_DIR, Context.MODE_PRIVATE);
String dexOutputPath = dexOutputDir.getAbsolutePath();
DexClassLoader loader = new DexClassLoader(apk.getAbsolutePath(), dexOutputPath, libsDir.getAbsolutePath(), parent);
......@@ -98,7 +94,7 @@ public final class LoadedPlugin {
return loader;
}
private static AssetManager createAssetManager(Context context, File apk) {
protected AssetManager createAssetManager(Context context, File apk) {
try {
AssetManager am = AssetManager.class.newInstance();
Reflector.with(am).method("addAssetPath", String.class).call(apk.getAbsolutePath());
......@@ -109,7 +105,7 @@ public final class LoadedPlugin {
}
}
private static Resources createResources(Context context, String packageName, File apk) throws Exception {
protected Resources createResources(Context context, String packageName, File apk) throws Exception {
if (Constants.COMBINE_RESOURCES) {
return ResourcesManager.createResources(context, packageName, apk);
} else {
......@@ -118,33 +114,45 @@ public final class LoadedPlugin {
return new Resources(assetManager, hostResources.getDisplayMetrics(), hostResources.getConfiguration());
}
}
protected PluginPackageManager createPluginPackageManager() {
return new PluginPackageManager();
}
public PluginContext createPluginContext(Context context) {
if (context == null) {
return new PluginContext(this);
}
return new PluginContext(this, context);
}
private static ResolveInfo chooseBestActivity(Intent intent, String s, int flags, List<ResolveInfo> query) {
protected ResolveInfo chooseBestActivity(Intent intent, String s, int flags, List<ResolveInfo> query) {
return query.get(0);
}
private final String mLocation;
private PluginManager mPluginManager;
private Context mHostContext;
private Context mPluginContext;
private final File mNativeLibDir;
private final PackageParser.Package mPackage;
private final PackageInfo mPackageInfo;
private Resources mResources;
private ClassLoader mClassLoader;
private PluginPackageManager mPackageManager;
private Map<ComponentName, ActivityInfo> mActivityInfos;
private Map<ComponentName, ServiceInfo> mServiceInfos;
private Map<ComponentName, ActivityInfo> mReceiverInfos;
private Map<ComponentName, ProviderInfo> mProviderInfos;
private Map<String, ProviderInfo> mProviders; // key is authorities of provider
private Map<ComponentName, InstrumentationInfo> mInstrumentationInfos;
private Application mApplication;
protected final String mLocation;
protected PluginManager mPluginManager;
protected Context mHostContext;
protected Context mPluginContext;
protected final File mNativeLibDir;
protected final PackageParser.Package mPackage;
protected final PackageInfo mPackageInfo;
protected Resources mResources;
protected ClassLoader mClassLoader;
protected PluginPackageManager mPackageManager;
protected Map<ComponentName, ActivityInfo> mActivityInfos;
protected Map<ComponentName, ServiceInfo> mServiceInfos;
protected Map<ComponentName, ActivityInfo> mReceiverInfos;
protected Map<ComponentName, ProviderInfo> mProviderInfos;
protected Map<String, ProviderInfo> mProviders; // key is authorities of provider
protected Map<ComponentName, InstrumentationInfo> mInstrumentationInfos;
protected Application mApplication;
@UiThread
LoadedPlugin(PluginManager pluginManager, Context context, File apk) throws Exception {
public LoadedPlugin(PluginManager pluginManager, Context context, File apk) throws Exception {
if (Thread.currentThread() != Looper.getMainLooper().getThread()) {
throw new RuntimeException("plugin mast be created by UI thread.");
}
......@@ -176,8 +184,8 @@ public final class LoadedPlugin {
this.mPackageInfo.versionCode = this.mPackage.mVersionCode;
this.mPackageInfo.versionName = this.mPackage.mVersionName;
this.mPackageInfo.permissions = new PermissionInfo[0];
this.mPackageManager = new PluginPackageManager();
this.mPluginContext = new PluginContext(this);
this.mPackageManager = createPluginPackageManager();
this.mPluginContext = createPluginContext(null);
this.mNativeLibDir = context.getDir(Constants.NATIVE_DIR, Context.MODE_PRIVATE);
this.mResources = createResources(context, getPackageName(), apk);
this.mClassLoader = createClassLoader(context, apk, this.mNativeLibDir, context.getClassLoader());
......@@ -233,7 +241,7 @@ public final class LoadedPlugin {
this.mPackageInfo.receivers = receivers.values().toArray(new ActivityInfo[receivers.size()]);
}
private void tryToCopyNativeLib(File apk) throws Exception {
protected void tryToCopyNativeLib(File apk) throws Exception {
PluginUtil.copyNativeLib(apk, mHostContext, mPackageInfo, mNativeLibDir);
}
......@@ -371,7 +379,7 @@ public final class LoadedPlugin {
Reflector.QuietReflector.with(this.mResources).field("mThemeResId").set(resid);
}
private Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
protected Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
if (null != this.mApplication) {
return this.mApplication;
}
......@@ -493,7 +501,7 @@ public final class LoadedPlugin {
return this.mProviders.get(name);
}
private boolean match(PackageParser.Component component, ComponentName target) {
protected boolean match(PackageParser.Component component, ComponentName target) {
ComponentName source = component.getComponentName();
if (source == target) return true;
if (source != null && target != null
......@@ -508,9 +516,9 @@ public final class LoadedPlugin {
/**
* @author johnsonlee
*/
private class PluginPackageManager extends PackageManager {
protected class PluginPackageManager extends PackageManager {
private PackageManager mHostPackageManager = mHostContext.getPackageManager();
protected PackageManager mHostPackageManager = mHostContext.getPackageManager();
@Override
public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
......
......@@ -86,7 +86,7 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
return mBase.execStartActivity(who, contextThread, token, target, intent, requestCode, options);
}
private void injectIntent(Intent intent) {
protected void injectIntent(Intent intent) {
mPluginManager.getComponentsHandler().transformIntentToExplicitAsNeeded(intent);
// null component is an implicitly intent
if (intent.getComponent() != null) {
......@@ -161,7 +161,7 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
mBase.callActivityOnCreate(activity, icicle, persistentState);
}
private void injectActivity(Activity activity) {
protected void injectActivity(Activity activity) {
final Intent intent = activity.getIntent();
if (PluginUtil.isIntentFromPlugin(intent)) {
Context base = activity.getBaseContext();
......@@ -169,7 +169,7 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
LoadedPlugin plugin = this.mPluginManager.getLoadedPlugin(intent);
Reflector.with(base).field("mResources").set(plugin.getResources());
Reflector reflector = Reflector.with(activity);
reflector.field("mBase").set(new PluginContext(plugin, activity.getBaseContext()));
reflector.field("mBase").set(plugin.createPluginContext(activity.getBaseContext()));
reflector.field("mApplication").set(plugin.getApplication());
// set screenOrientation
......@@ -224,7 +224,7 @@ public class VAInstrumentation extends Instrumentation implements Handler.Callba
return mBase.getComponentName();
}
private Activity newActivity(Activity activity) {
protected Activity newActivity(Activity activity) {
synchronized (mActivities) {
for (int i = mActivities.size() - 1; i >= 0; i--) {
if (mActivities.get(i).get() == null) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册