feat(plugins): get config and cache dirs for plugins
This commit is contained in:
@@ -9,6 +9,7 @@ plugins {
|
||||
dependencies {
|
||||
implementation(project(":jadx-core"))
|
||||
implementation(project(":jadx-plugins-tools"))
|
||||
implementation(project(":jadx-commons:jadx-app-commons"))
|
||||
|
||||
runtimeOnly(project(":jadx-plugins:jadx-dex-input"))
|
||||
runtimeOnly(project(":jadx-plugins:jadx-java-input"))
|
||||
|
||||
@@ -9,6 +9,7 @@ import jadx.api.impl.AnnotatedCodeWriter;
|
||||
import jadx.api.impl.NoOpCodeCache;
|
||||
import jadx.api.impl.SimpleCodeWriter;
|
||||
import jadx.cli.LogHelper.LogLevelEnum;
|
||||
import jadx.cli.plugins.JadxFilesGetter;
|
||||
import jadx.core.utils.exceptions.JadxArgsValidateException;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
import jadx.plugins.tools.JadxExternalPluginsLoader;
|
||||
@@ -46,6 +47,7 @@ public class JadxCLI {
|
||||
JadxArgs jadxArgs = cliArgs.toJadxArgs();
|
||||
jadxArgs.setCodeCache(new NoOpCodeCache());
|
||||
jadxArgs.setPluginLoader(new JadxExternalPluginsLoader());
|
||||
jadxArgs.setFilesGetter(JadxFilesGetter.INSTANCE);
|
||||
initCodeWriterProvider(jadxArgs);
|
||||
try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) {
|
||||
jadx.load();
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package jadx.cli.plugins;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import jadx.commons.app.JadxCommonFiles;
|
||||
import jadx.core.plugins.files.IJadxFilesGetter;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
|
||||
public class JadxFilesGetter implements IJadxFilesGetter {
|
||||
|
||||
public static final JadxFilesGetter INSTANCE = new JadxFilesGetter();
|
||||
|
||||
@Override
|
||||
public Path getConfigDir() {
|
||||
return JadxCommonFiles.getConfigDir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getCacheDir() {
|
||||
return JadxCommonFiles.getCacheDir();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getTempDir() {
|
||||
return FileUtils.getTempRootDir();
|
||||
}
|
||||
|
||||
private JadxFilesGetter() {
|
||||
// singleton
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,8 @@ import jadx.core.deobf.DeobfAliasProvider;
|
||||
import jadx.core.deobf.conditions.DeobfWhitelist;
|
||||
import jadx.core.deobf.conditions.JadxRenameConditions;
|
||||
import jadx.core.plugins.PluginContext;
|
||||
import jadx.core.plugins.files.IJadxFilesGetter;
|
||||
import jadx.core.plugins.files.TempFilesGetter;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
|
||||
public class JadxArgs implements Closeable {
|
||||
@@ -166,6 +168,12 @@ public class JadxArgs implements Closeable {
|
||||
|
||||
private UseKotlinMethodsForVarNames useKotlinMethodsForVarNames = UseKotlinMethodsForVarNames.APPLY;
|
||||
|
||||
/**
|
||||
* Additional files structure info.
|
||||
* Defaults to tmp dirs.
|
||||
*/
|
||||
private IJadxFilesGetter filesGetter = TempFilesGetter.INSTANCE;
|
||||
|
||||
/**
|
||||
* Don't save files (can be using for performance testing)
|
||||
*/
|
||||
@@ -710,6 +718,14 @@ public class JadxArgs implements Closeable {
|
||||
this.useKotlinMethodsForVarNames = useKotlinMethodsForVarNames;
|
||||
}
|
||||
|
||||
public IJadxFilesGetter getFilesGetter() {
|
||||
return filesGetter;
|
||||
}
|
||||
|
||||
public void setFilesGetter(IJadxFilesGetter filesGetter) {
|
||||
this.filesGetter = filesGetter;
|
||||
}
|
||||
|
||||
public boolean isSkipFilesSave() {
|
||||
return skipFilesSave;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.api.plugins.data.IJadxFiles;
|
||||
import jadx.api.plugins.data.IJadxPlugins;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.gui.JadxGuiContext;
|
||||
@@ -53,4 +54,9 @@ public interface JadxPluginContext {
|
||||
* Access to registered plugins and runtime data
|
||||
*/
|
||||
IJadxPlugins plugins();
|
||||
|
||||
/**
|
||||
* Access to plugin specific files and directories
|
||||
*/
|
||||
IJadxFiles files();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package jadx.api.plugins.data;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IJadxFiles {
|
||||
|
||||
/**
|
||||
* Plugin cache directory.
|
||||
*/
|
||||
Path getPluginCacheDir();
|
||||
|
||||
/**
|
||||
* Plugin config directory.
|
||||
*/
|
||||
Path getPluginConfigDir();
|
||||
|
||||
/**
|
||||
* Plugin temp directory.
|
||||
*/
|
||||
Path getPluginTempDir();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package jadx.core.plugins;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.gui.JadxGuiContext;
|
||||
import jadx.core.plugins.files.IJadxFilesGetter;
|
||||
|
||||
public class AppContext {
|
||||
|
||||
private @Nullable JadxGuiContext guiContext;
|
||||
|
||||
private IJadxFilesGetter filesGetter;
|
||||
|
||||
public @Nullable JadxGuiContext getGuiContext() {
|
||||
return guiContext;
|
||||
}
|
||||
|
||||
public void setGuiContext(@Nullable JadxGuiContext guiContext) {
|
||||
this.guiContext = guiContext;
|
||||
}
|
||||
|
||||
public IJadxFilesGetter getFilesGetter() {
|
||||
return Objects.requireNonNull(filesGetter);
|
||||
}
|
||||
|
||||
public void setFilesGetter(IJadxFilesGetter filesGetter) {
|
||||
this.filesGetter = filesGetter;
|
||||
}
|
||||
}
|
||||
@@ -122,8 +122,12 @@ public class JadxPluginManager {
|
||||
}
|
||||
|
||||
public void init(SortedSet<PluginContext> pluginContexts) {
|
||||
AppContext defAppContext = buildDefaultAppContext();
|
||||
for (PluginContext context : pluginContexts) {
|
||||
try {
|
||||
if (context.getAppContext() == null) {
|
||||
context.setAppContext(defAppContext);
|
||||
}
|
||||
context.init();
|
||||
} catch (Exception e) {
|
||||
throw new JadxRuntimeException("Failed to init plugin: " + context.getPluginId(), e);
|
||||
@@ -137,6 +141,13 @@ public class JadxPluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
private AppContext buildDefaultAppContext() {
|
||||
AppContext appContext = new AppContext();
|
||||
appContext.setGuiContext(null);
|
||||
appContext.setFilesGetter(decompiler.getArgs().getFilesGetter());
|
||||
return appContext;
|
||||
}
|
||||
|
||||
private void verifyOptions(PluginContext pluginContext, JadxPluginOptions options) {
|
||||
String pluginId = pluginContext.getPluginId();
|
||||
List<OptionDescription> descriptions = options.getOptionsDescriptions();
|
||||
|
||||
@@ -15,6 +15,7 @@ import jadx.api.JadxDecompiler;
|
||||
import jadx.api.plugins.JadxPlugin;
|
||||
import jadx.api.plugins.JadxPluginContext;
|
||||
import jadx.api.plugins.JadxPluginInfo;
|
||||
import jadx.api.plugins.data.IJadxFiles;
|
||||
import jadx.api.plugins.data.IJadxPlugins;
|
||||
import jadx.api.plugins.data.JadxPluginRuntimeData;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
@@ -27,6 +28,7 @@ import jadx.api.plugins.options.OptionDescription;
|
||||
import jadx.api.plugins.options.OptionFlag;
|
||||
import jadx.api.plugins.pass.JadxPass;
|
||||
import jadx.api.plugins.resources.IResourcesLoader;
|
||||
import jadx.core.plugins.files.JadxFilesData;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
@@ -36,7 +38,8 @@ public class PluginContext implements JadxPluginContext, JadxPluginRuntimeData,
|
||||
private final JadxPluginsData pluginsData;
|
||||
private final JadxPlugin plugin;
|
||||
private final JadxPluginInfo pluginInfo;
|
||||
private @Nullable JadxGuiContext guiContext;
|
||||
|
||||
private AppContext appContext;
|
||||
|
||||
private final List<JadxCodeInput> codeInputs = new ArrayList<>();
|
||||
private @Nullable JadxPluginOptions options;
|
||||
@@ -137,13 +140,17 @@ public class PluginContext implements JadxPluginContext, JadxPluginRuntimeData,
|
||||
return decompiler.getResourcesLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable JadxGuiContext getGuiContext() {
|
||||
return guiContext;
|
||||
public AppContext getAppContext() {
|
||||
return appContext;
|
||||
}
|
||||
|
||||
public void setGuiContext(JadxGuiContext guiContext) {
|
||||
this.guiContext = guiContext;
|
||||
public void setAppContext(AppContext appContext) {
|
||||
this.appContext = appContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable JadxGuiContext getGuiContext() {
|
||||
return appContext.getGuiContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,6 +178,11 @@ public class PluginContext implements JadxPluginContext, JadxPluginRuntimeData,
|
||||
return pluginsData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxFiles files() {
|
||||
return new JadxFilesData(pluginInfo, appContext.getFilesGetter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeLoader loadCodeFiles(List<Path> files, @Nullable Closeable closeable) {
|
||||
return new MergeCodeLoader(
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package jadx.core.plugins.files;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IJadxFilesGetter {
|
||||
|
||||
Path getConfigDir();
|
||||
|
||||
Path getCacheDir();
|
||||
|
||||
Path getTempDir();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package jadx.core.plugins.files;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import jadx.api.plugins.JadxPluginInfo;
|
||||
import jadx.api.plugins.data.IJadxFiles;
|
||||
|
||||
public class JadxFilesData implements IJadxFiles {
|
||||
private static final String PLUGINS_DATA_DIR = "plugins-data";
|
||||
|
||||
private final JadxPluginInfo pluginInfo;
|
||||
private final IJadxFilesGetter filesGetter;
|
||||
|
||||
public JadxFilesData(JadxPluginInfo pluginInfo, IJadxFilesGetter filesGetter) {
|
||||
this.pluginInfo = pluginInfo;
|
||||
this.filesGetter = filesGetter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPluginCacheDir() {
|
||||
return toPluginPath(filesGetter.getCacheDir());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPluginConfigDir() {
|
||||
return toPluginPath(filesGetter.getConfigDir());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPluginTempDir() {
|
||||
return toPluginPath(filesGetter.getTempDir());
|
||||
}
|
||||
|
||||
private Path toPluginPath(Path dir) {
|
||||
return dir.resolve(PLUGINS_DATA_DIR).resolve(pluginInfo.getPluginId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package jadx.core.plugins.files;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
|
||||
public class TempFilesGetter implements IJadxFilesGetter {
|
||||
|
||||
public static final TempFilesGetter INSTANCE = new TempFilesGetter();
|
||||
|
||||
@Override
|
||||
public Path getConfigDir() {
|
||||
return FileUtils.getTempRootDir().resolve("config");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getCacheDir() {
|
||||
return FileUtils.getTempRootDir().resolve("cache");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getTempDir() {
|
||||
return FileUtils.getTempRootDir().resolve("temp");
|
||||
}
|
||||
|
||||
private TempFilesGetter() {
|
||||
// singleton
|
||||
}
|
||||
}
|
||||
@@ -168,6 +168,10 @@ public class FileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static Path getTempRootDir() {
|
||||
return TEMP_ROOT_DIR;
|
||||
}
|
||||
|
||||
public static void deleteTempRootDir() {
|
||||
deleteDirIfExists(TEMP_ROOT_DIR);
|
||||
}
|
||||
|
||||
@@ -23,16 +23,17 @@ import jadx.api.impl.InMemoryCodeCache;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.api.usage.impl.EmptyUsageInfoCache;
|
||||
import jadx.api.usage.impl.InMemoryUsageInfoCache;
|
||||
import jadx.cli.plugins.JadxFilesGetter;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.ProcessState;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.plugins.AppContext;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.gui.cache.code.CodeStringCache;
|
||||
import jadx.gui.cache.code.disk.BufferCodeCache;
|
||||
import jadx.gui.cache.code.disk.DiskCodeCache;
|
||||
import jadx.gui.cache.usage.UsageInfoCache;
|
||||
import jadx.gui.plugins.context.CommonGuiPluginsContext;
|
||||
import jadx.gui.plugins.context.GuiPluginContext;
|
||||
import jadx.gui.settings.JadxProject;
|
||||
import jadx.gui.settings.JadxSettings;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
@@ -67,7 +68,7 @@ public class JadxWrapper {
|
||||
project.fillJadxArgs(jadxArgs);
|
||||
|
||||
decompiler = new JadxDecompiler(jadxArgs);
|
||||
initGuiPluginsContext();
|
||||
guiPluginsContext = initGuiPluginsContext(decompiler, mainWindow);
|
||||
initUsageCache(jadxArgs);
|
||||
decompiler.load();
|
||||
initCodeCache();
|
||||
@@ -139,12 +140,15 @@ public class JadxWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private void initGuiPluginsContext() {
|
||||
guiPluginsContext = new CommonGuiPluginsContext(mainWindow);
|
||||
public static CommonGuiPluginsContext initGuiPluginsContext(JadxDecompiler decompiler, MainWindow mainWindow) {
|
||||
CommonGuiPluginsContext guiPluginsContext = new CommonGuiPluginsContext(mainWindow);
|
||||
decompiler.getPluginManager().registerAddPluginListener(pluginContext -> {
|
||||
GuiPluginContext guiContext = guiPluginsContext.buildForPlugin(pluginContext);
|
||||
pluginContext.setGuiContext(guiContext);
|
||||
AppContext appContext = new AppContext();
|
||||
appContext.setGuiContext(guiPluginsContext.buildForPlugin(pluginContext));
|
||||
appContext.setFilesGetter(JadxFilesGetter.INSTANCE);
|
||||
pluginContext.setAppContext(appContext);
|
||||
});
|
||||
return guiPluginsContext;
|
||||
}
|
||||
|
||||
public CommonGuiPluginsContext getGuiPluginsContext() {
|
||||
|
||||
@@ -9,8 +9,7 @@ import jadx.api.JadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.core.plugins.JadxPluginManager;
|
||||
import jadx.core.plugins.PluginContext;
|
||||
import jadx.gui.plugins.context.CommonGuiPluginsContext;
|
||||
import jadx.gui.plugins.context.GuiPluginContext;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.plugins.tools.JadxExternalPluginsLoader;
|
||||
|
||||
@@ -36,11 +35,7 @@ public class CollectPlugins {
|
||||
try (JadxDecompiler decompiler = new JadxDecompiler(new JadxArgs())) {
|
||||
JadxPluginManager pluginManager = decompiler.getPluginManager();
|
||||
pluginManager.load(new JadxExternalPluginsLoader());
|
||||
CommonGuiPluginsContext guiPluginsContext = new CommonGuiPluginsContext(mainWindow);
|
||||
decompiler.getPluginManager().registerAddPluginListener(pluginContext -> {
|
||||
GuiPluginContext guiContext = guiPluginsContext.buildForPlugin(pluginContext);
|
||||
pluginContext.setGuiContext(guiContext);
|
||||
});
|
||||
JadxWrapper.initGuiPluginsContext(decompiler, mainWindow);
|
||||
SortedSet<PluginContext> missingPlugins = new TreeSet<>();
|
||||
for (PluginContext context : pluginManager.getAllPluginContexts()) {
|
||||
if (!allPlugins.contains(context)) {
|
||||
|
||||
Reference in New Issue
Block a user