diff --git a/autojs/src/main/java/com/stardust/autojs/core/plugin/Plugin.java b/autojs/src/main/java/com/stardust/autojs/core/plugin/Plugin.java index 373ce64d..b16542da 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/plugin/Plugin.java +++ b/autojs/src/main/java/com/stardust/autojs/core/plugin/Plugin.java @@ -1,15 +1,20 @@ package com.stardust.autojs.core.plugin; +import android.content.ComponentName; import android.content.Context; +import android.content.ServiceConnection; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.os.IBinder; +import android.util.Log; import com.stardust.autojs.rhino.TopLevelScope; import com.stardust.autojs.runtime.ScriptRuntime; import java.lang.reflect.Method; -public class Plugin { +public class Plugin implements ServiceConnection { + private static final String TAG = "Plugin"; public static class PluginLoadException extends RuntimeException { public PluginLoadException(Throwable cause) { @@ -36,7 +41,7 @@ public class Plugin { } catch (PackageManager.NameNotFoundException e) { return null; } catch (Throwable e) { - e.printStackTrace(); + Log.e(TAG, "load failed", e); throw new PluginLoadException(e); } } @@ -47,10 +52,17 @@ public class Plugin { return new Plugin(pluginInstance); } - private final Object mPluginInstance; + private Object mPluginInstance; private Method mGetVersion; private Method mGetScriptDir; private String mMainScriptPath; + // AIDL 调用 + private Method mGetService; + private Method mOnServiceConnected; + private Method mOnServiceDisconnected; + private ComponentName componentName; + + private int version; public Plugin(Object pluginInstance) { mPluginInstance = pluginInstance; @@ -59,18 +71,65 @@ public class Plugin { @SuppressWarnings("unchecked") private void findMethods(Class pluginClass) { - try { - mGetVersion = pluginClass.getMethod("getVersion"); - } catch (NoSuchMethodException e) { - e.printStackTrace(); + mGetVersion = findMethod(pluginClass, "getVersion"); + mGetScriptDir = findMethod(pluginClass, "getAssetsScriptDir"); + mGetService = findMethod(pluginClass, "getService"); + mOnServiceConnected = findMethod(pluginClass, "onServiceConnected", ComponentName.class, IBinder.class); + mOnServiceDisconnected = findMethod(pluginClass, "onServiceDisconnected", ComponentName.class); + if (mGetService != null) { + try { + componentName = (ComponentName) mGetService.invoke(mPluginInstance); + } catch (Exception e) { + Log.e(TAG, "get componentName failed ", e); + } } try { - mGetScriptDir = pluginClass.getMethod("getAssetsScriptDir"); - } catch (NoSuchMethodException e) { - e.printStackTrace(); + if (mGetVersion != null) { + version = (int) mGetVersion.invoke(mPluginInstance); + } + } catch (Exception e) { + Log.e(TAG, "get version failed ", e); } } + + + @Override + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + Log.d(TAG, "onServiceConnected: " + componentName.getShortClassName()); + if (mOnServiceConnected == null) { + return; + } + try { + mOnServiceConnected.invoke(mPluginInstance, componentName, iBinder); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + Log.d(TAG, "onServiceDisconnected: " + componentName.getShortClassName()); + if (mOnServiceDisconnected == null) { + return; + } + try { + mOnServiceDisconnected.invoke(mPluginInstance, componentName); + } catch (Exception e) { + throw new RuntimeException(e); + } + mPluginInstance = null; + } + + private Method findMethod(Class pluginClass, String method, Class ...args) { + try { + return pluginClass.getMethod(method, args); + } catch (NoSuchMethodException e) { + Log.d(TAG, "can not findMethod: "+ method, e); + } + return null; + } + public Object unwrap() { return mPluginInstance; } @@ -90,4 +149,12 @@ public class Plugin { throw new RuntimeException(e); } } + + public ComponentName getComponentName() { + return componentName; + } + + public int getVersion() { + return version; + } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/Plugins.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/Plugins.java index 9a7b60b2..8039bc68 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/Plugins.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/Plugins.java @@ -1,6 +1,9 @@ package com.stardust.autojs.runtime.api; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; +import android.util.Log; import com.stardust.autojs.core.plugin.Plugin; import com.stardust.autojs.runtime.ScriptRuntime; @@ -31,12 +34,30 @@ public class Plugins { File scriptCacheDir = getScriptCacheDir(packageName); PFiles.copyAssetDir(packageContext.getAssets(), plugin.getAssetsScriptDir(), scriptCacheDir.getPath(), null); plugin.setMainScriptPath(new File(scriptCacheDir, "index.js").getPath()); + bindService(plugin); return plugin; } catch (Exception e) { throw new Plugin.PluginLoadException(e); } } + private void bindService(Plugin plugin) { + if (plugin.getVersion() < 2) { + return; + } + ComponentName componentName = plugin.getComponentName(); + if (componentName == null) { + return; + } + Intent intent = new Intent(); + intent.setComponent(componentName); + try { + mContext.getApplicationContext().bindService(intent, plugin, Context.BIND_AUTO_CREATE); + } catch (Exception e) { + Log.e("Plugins", "bindService failed", e); + } + } + private File getScriptCacheDir(String packageName) { File dir = new File(mPluginCacheDir, packageName + "/"); dir.mkdirs();