Skip to content

Commit

Permalink
feat: allow to disable installed plugins (#2277)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Oct 28, 2024
1 parent 4d8a5d6 commit cc6a893
Show file tree
Hide file tree
Showing 33 changed files with 358 additions and 90 deletions.
60 changes: 49 additions & 11 deletions jadx-cli/src/main/java/jadx/cli/commands/CommandPlugins.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public class CommandPlugins implements ICommand {
@Parameter(names = { "--uninstall" }, description = "uninstall plugin with pluginId")
protected String uninstall;

@Parameter(names = { "--disable" }, description = "disable plugin with pluginId")
protected String disable;

@Parameter(names = { "--enable" }, description = "enable plugin with pluginId")
protected String enable;

@Parameter(names = { "-h", "--help" }, description = "print this help", help = true)
protected boolean printHelp = false;

Expand All @@ -47,6 +53,10 @@ public void process(JCommanderWrapper<?> jcw, JCommander subCommander) {
jcw.printUsage(subCommander);
return;
}
if (!subCommander.getUnknownOptions().isEmpty()) {
System.out.println("Error: found unknown options: " + subCommander.getUnknownOptions());
}

if (install != null) {
installPlugin(install);
}
Expand All @@ -69,26 +79,54 @@ public void process(JCommanderWrapper<?> jcw, JCommander subCommander) {
}
}
if (list) {
List<JadxPluginMetadata> installed = JadxPluginsTools.getInstance().getInstalled();
System.out.println("Installed plugins: " + installed.size());
int i = 1;
for (JadxPluginMetadata plugin : installed) {
System.out.println(" " + (i++) + ") "
+ plugin.getPluginId() + " (" + plugin.getVersion() + ") - "
+ plugin.getName() + ": " + plugin.getDescription());
}
printInstalledPlugins();
}

if (available) {
List<JadxPluginMetadata> availableList = JadxPluginsList.getInstance().get();
System.out.println("Available plugins: " + availableList.size());
int i = 1;
for (JadxPluginMetadata plugin : availableList) {
System.out.println(" " + (i++) + ") "
+ plugin.getName() + ": " + plugin.getDescription()
System.out.println(" - " + plugin.getName() + ": " + plugin.getDescription()
+ " (" + plugin.getLocationId() + ")");
}
}

if (disable != null) {
if (JadxPluginsTools.getInstance().changeDisabledStatus(disable, true)) {
System.out.println("Plugin '" + disable + "' disabled.");
} else {
System.out.println("Plugin '" + disable + "' already disabled.");
}
}
if (enable != null) {
if (JadxPluginsTools.getInstance().changeDisabledStatus(enable, false)) {
System.out.println("Plugin '" + enable + "' enabled.");
} else {
System.out.println("Plugin '" + enable + "' already enabled.");
}
}
}

private static void printInstalledPlugins() {
List<JadxPluginMetadata> installed = JadxPluginsTools.getInstance().getInstalled();
System.out.println("Installed plugins: " + installed.size());
for (JadxPluginMetadata plugin : installed) {
StringBuilder sb = new StringBuilder();
sb.append(" - ");
sb.append(plugin.getPluginId());
String version = plugin.getVersion();
if (version != null) {
sb.append(" (").append(version).append(')');
}
if (plugin.isDisabled()) {
sb.append(" (disabled)");
}
sb.append(" - ");
sb.append(plugin.getName());
sb.append(": ");
sb.append(plugin.getDescription());
System.out.println(sb);
}
}

private void installPlugin(String locationId) {
Expand Down
7 changes: 6 additions & 1 deletion jadx-core/src/main/java/jadx/api/JadxDecompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,14 @@ public final class JadxDecompiler implements Closeable {
private List<ResourceFile> resources;

private final IDecompileScheduler decompileScheduler = new DecompilerScheduler();
private final JadxEventsImpl events = new JadxEventsImpl();
private final ResourcesLoader resourcesLoader = new ResourcesLoader(this);

private final List<ICodeLoader> customCodeLoaders = new ArrayList<>();
private final List<CustomResourcesLoader> customResourcesLoaders = new ArrayList<>();
private final Map<JadxPassType, List<JadxPass>> customPasses = new HashMap<>();

private IJadxEvents events = new JadxEventsImpl();

public JadxDecompiler() {
this(new JadxArgs());
}
Expand Down Expand Up @@ -666,6 +667,10 @@ public IJadxEvents events() {
return events;
}

public void setEventsImpl(IJadxEvents eventsImpl) {
this.events = eventsImpl;
}

public void addCustomCodeLoader(ICodeLoader customCodeLoader) {
customCodeLoaders.add(customCodeLoader);
}
Expand Down
11 changes: 11 additions & 0 deletions jadx-core/src/main/java/jadx/api/plugins/events/IJadxEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,15 @@ public interface IJadxEvents {
* For public event types check {@link JadxEvents} class.
*/
<E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener);

/**
* Remove listener for specific event.
* Listener should be same or equal object.
*/
<E extends IJadxEvent> void removeListener(JadxEventType<E> eventType, Consumer<E> listener);

/**
* Clear all listeners.
*/
void reset();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,13 @@ public static <E extends IJadxEvent> JadxEventType<E> create() {
return new JadxEventType<>() {
};
}

public static <E extends IJadxEvent> JadxEventType<E> create(String name) {
return new JadxEventType<>() {
@Override
public String toString() {
return name;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ public class JadxEvents {
/**
* Notify about renaming done by user (GUI only).
*/
public static final JadxEventType<NodeRenamedByUser> NODE_RENAMED_BY_USER = create();
public static final JadxEventType<NodeRenamedByUser> NODE_RENAMED_BY_USER = create("NODE_RENAMED_BY_USER");

/**
* Request reload of a current project (GUI only).
*/
public static final JadxEventType<ReloadProject> RELOAD_PROJECT = create();
public static final JadxEventType<ReloadProject> RELOAD_PROJECT = create("RELOAD_PROJECT");

/**
* Request reload of a settings window (GUI only).
* Useful for a reload custom settings group which was set with
* {@link JadxGuiSettings#setCustomSettingsGroup(ISettingsGroup)}.
*/
public static final JadxEventType<ReloadSettingsWindow> RELOAD_SETTINGS_WINDOW = create();
public static final JadxEventType<ReloadSettingsWindow> RELOAD_SETTINGS_WINDOW = create("RELOAD_SETTINGS_WINDOW");
}
2 changes: 1 addition & 1 deletion jadx-core/src/main/java/jadx/core/Consts.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class Consts {
public static final boolean DEBUG_FINALLY = false;
public static final boolean DEBUG_ATTRIBUTES = false;
public static final boolean DEBUG_RESTRUCTURE = false;
public static final boolean DEBUG_EVENTS = true;
public static final boolean DEBUG_EVENTS = Jadx.isDevVersion();

public static final String CLASS_OBJECT = "java.lang.Object";
public static final String CLASS_STRING = "java.lang.String";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,20 @@ public void send(IJadxEvent event) {
@Override
public <E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener) {
manager.addListener(eventType, listener);
if (Consts.DEBUG_EVENTS) {
LOG.debug("add listener for: {}, stats: {}", eventType, manager.listenersDebugStats());
}
}

@Override
public <E extends IJadxEvent> void removeListener(JadxEventType<E> eventType, Consumer<E> listener) {
manager.removeListener(eventType, listener);
if (Consts.DEBUG_EVENTS) {
LOG.debug("remove listener for: {}, stats: {}", eventType, manager.listenersDebugStats());
}
}

@Override
public void reset() {
manager.reset();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;

Expand All @@ -35,6 +36,14 @@ public synchronized <E extends IJadxEvent> void addListener(JadxEventType<E> eve
.add((Consumer<IJadxEvent>) listener);
}

public synchronized <E extends IJadxEvent> boolean removeListener(JadxEventType<E> eventType, Consumer<E> listener) {
List<Consumer<IJadxEvent>> eventListeners = listeners.get(eventType);
if (eventListeners != null) {
return eventListeners.remove(listener);
}
return false;
}

public synchronized void send(IJadxEvent event) {
List<Consumer<IJadxEvent>> consumers = listeners.get(event.getType());
if (consumers != null) {
Expand All @@ -58,4 +67,12 @@ public Thread newThread(@NotNull Runnable r) {
}
};
}

public String listenersDebugStats() {
return listeners.entrySet()
.stream()
.filter(p -> !p.getValue().isEmpty())
.map(p -> p.getKey() + ":" + p.getValue().size())
.collect(Collectors.joining(", ", "[", "]"));
}
}
7 changes: 7 additions & 0 deletions jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ public void open() {
decompiler = new JadxDecompiler(jadxArgs);
guiPluginsContext = initGuiPluginsContext(decompiler, mainWindow);
initUsageCache(jadxArgs);
decompiler.setEventsImpl(mainWindow.events());

decompiler.load();
initCodeCache();
}
Expand Down Expand Up @@ -159,6 +161,11 @@ public void resetGuiPluginsContext() {
guiPluginsContext.reset();
}

public void reloadPasses() {
resetGuiPluginsContext();
decompiler.reloadPasses();
}

/**
* Get the complete list of classes
*/
Expand Down
2 changes: 1 addition & 1 deletion jadx-gui/src/main/java/jadx/gui/events/JadxGuiEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

public class JadxGuiEvents {

public static final JadxEventType<TreeUpdate> TREE_UPDATE = create();
public static final JadxEventType<TreeUpdate> TREE_UPDATE = create("TREE_UPDATE");
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class RenameService {

public static void init(MainWindow mainWindow) {
RenameService renameService = new RenameService(mainWindow);
mainWindow.events().addListener(JadxEvents.NODE_RENAMED_BY_USER, renameService::process);
mainWindow.events().global().addListener(JadxEvents.NODE_RENAMED_BY_USER, renameService::process);
}

private final MainWindow mainWindow;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package jadx.gui.events.types;

import java.util.function.Consumer;

import jadx.api.plugins.events.IJadxEvent;
import jadx.api.plugins.events.IJadxEvents;
import jadx.api.plugins.events.JadxEventType;
import jadx.core.plugins.events.JadxEventsImpl;

/**
* Special events implementation to operate on both: global UI and project events.
* Project events hold listeners only while a project opened and reset them on close.
*/
public class JadxGuiEventsImpl implements IJadxEvents {

private final IJadxEvents global = new JadxEventsImpl();
private final IJadxEvents project = new JadxEventsImpl();

public IJadxEvents global() {
return global;
}

@Override
public void send(IJadxEvent event) {
global.send(event);
project.send(event);
}

@Override
public <E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener) {
project.addListener(eventType, listener);
}

@Override
public <E extends IJadxEvent> void removeListener(JadxEventType<E> eventType, Consumer<E> listener) {
project.removeListener(eventType, listener);
}

@Override
public void reset() {
project.reset();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import kotlin.script.experimental.api.ScriptDiagnostic;
import kotlin.script.experimental.api.ScriptDiagnostic.Severity;

import jadx.gui.JadxWrapper;
import jadx.gui.logs.LogOptions;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.LineNumbersMode;
Expand Down Expand Up @@ -137,9 +136,7 @@ private void runScript() {
MainWindow mainWindow = tabbedPane.getMainWindow();
mainWindow.getBackgroundExecutor().execute(NLS.str("script.run"), () -> {
try {
JadxWrapper wrapper = mainWindow.getWrapper();
wrapper.resetGuiPluginsContext();
wrapper.getDecompiler().reloadPasses();
mainWindow.getWrapper().reloadPasses();
} catch (Exception e) {
scriptLog.error("Passes reload failed", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;

import javax.swing.BorderFactory;
import javax.swing.Box;
Expand Down Expand Up @@ -54,6 +55,7 @@
import jadx.api.args.ResourceNameSource;
import jadx.api.args.UseSourceNameAsClassNameAlias;
import jadx.api.plugins.events.JadxEvents;
import jadx.api.plugins.events.types.ReloadSettingsWindow;
import jadx.api.plugins.gui.ISettingsGroup;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.JadxSettingsAdapter;
Expand Down Expand Up @@ -85,6 +87,7 @@ public class JadxSettingsWindow extends JDialog {
private final transient String startSettings;
private final transient String startSettingsHash;
private final transient LangLocale prevLang;
private final transient Consumer<ReloadSettingsWindow> reloadListener;

private transient boolean needReload = false;
private transient SettingsTree tree;
Expand All @@ -107,8 +110,8 @@ public JadxSettingsWindow(MainWindow mainWindow, JadxSettings settings) {
if (!mainWindow.getSettings().loadWindowPos(this)) {
setSize(700, 800);
}
mainWindow.events().addListener(JadxEvents.RELOAD_SETTINGS_WINDOW, r -> UiUtils.uiRun(this::reloadUI));
mainWindow.events().addListener(JadxEvents.RELOAD_PROJECT, r -> UiUtils.uiRun(this::reloadUI));
reloadListener = ev -> UiUtils.uiRun(this::reloadUI);
mainWindow.events().global().addListener(JadxEvents.RELOAD_SETTINGS_WINDOW, reloadListener);
}

private void reloadUI() {
Expand Down Expand Up @@ -773,6 +776,7 @@ public MainWindow getMainWindow() {

@Override
public void dispose() {
mainWindow.events().global().removeListener(JadxEvents.RELOAD_SETTINGS_WINDOW, reloadListener);
settings.saveWindowPos(this);
super.dispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ public String getHomepage() {
return null;
}

public boolean isDisabled() {
return false;
}

public PluginAction getAction() {
return PluginAction.NONE;
}
Expand Down
Loading

0 comments on commit cc6a893

Please sign in to comment.