Refactor Manager and SignalAccount to implement Closeable

Should make sure that file lock and web socket connections are closed
reliably.
This commit is contained in:
AsamK 2020-05-13 23:33:40 +02:00
parent 87f65de0c5
commit d520023fc7
4 changed files with 224 additions and 164 deletions

View file

@ -44,6 +44,7 @@ import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedE
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.File;
import java.io.IOException;
import java.security.Security;
import java.util.Map;
@ -71,94 +72,122 @@ public class Main {
private static int handleCommands(Namespace ns) {
final String username = ns.getString("username");
Manager m = null;
ProvisioningManager pm = null;
Signal ts;
DBusConnection dBusConn = null;
try {
if (ns.getBoolean("dbus") || ns.getBoolean("dbus_system")) {
try {
DBusConnection.DBusBusType busType;
if (ns.getBoolean("dbus_system")) {
busType = DBusConnection.DBusBusType.SYSTEM;
} else {
busType = DBusConnection.DBusBusType.SESSION;
}
dBusConn = DBusConnection.getConnection(busType);
ts = dBusConn.getRemoteObject(
if (ns.getBoolean("dbus") || ns.getBoolean("dbus_system")) {
try {
DBusConnection.DBusBusType busType;
if (ns.getBoolean("dbus_system")) {
busType = DBusConnection.DBusBusType.SYSTEM;
} else {
busType = DBusConnection.DBusBusType.SESSION;
}
try (DBusConnection dBusConn = DBusConnection.getConnection(busType)) {
Signal ts = dBusConn.getRemoteObject(
DbusConfig.SIGNAL_BUSNAME, DbusConfig.SIGNAL_OBJECTPATH,
Signal.class);
} catch (UnsatisfiedLinkError e) {
System.err.println("Missing native library dependency for dbus service: " + e.getMessage());
return 1;
} catch (DBusException e) {
e.printStackTrace();
if (dBusConn != null) {
dBusConn.disconnect();
}
return 3;
}
} else {
String dataPath = ns.getString("config");
if (isEmpty(dataPath)) {
dataPath = getDefaultDataPath();
}
if (username == null) {
pm = new ProvisioningManager(dataPath, ServiceConfig.createDefaultServiceConfiguration(BaseConfig.USER_AGENT), BaseConfig.USER_AGENT);
ts = null;
} else {
try {
m = Manager.init(username, dataPath, ServiceConfig.createDefaultServiceConfiguration(BaseConfig.USER_AGENT), BaseConfig.USER_AGENT);
} catch (AuthorizationFailedException e) {
if (!"register".equals(ns.getString("command"))) {
// Register command should still be possible, if current authorization fails
System.err.println("Authorization failed, was the number registered elsewhere?");
return 2;
}
} catch (Throwable e) {
System.err.println("Error loading state file: " + e.getMessage());
return handleCommands(ns, ts, dBusConn);
}
} catch (UnsatisfiedLinkError e) {
System.err.println("Missing native library dependency for dbus service: " + e.getMessage());
return 1;
} catch (DBusException | IOException e) {
e.printStackTrace();
return 3;
}
} else {
String dataPath = ns.getString("config");
if (isEmpty(dataPath)) {
dataPath = getDefaultDataPath();
}
if (username == null) {
ProvisioningManager pm = new ProvisioningManager(dataPath, ServiceConfig.createDefaultServiceConfiguration(BaseConfig.USER_AGENT), BaseConfig.USER_AGENT);
return handleCommands(ns, pm);
}
Manager manager;
try {
manager = Manager.init(username, dataPath, ServiceConfig.createDefaultServiceConfiguration(BaseConfig.USER_AGENT), BaseConfig.USER_AGENT);
} catch (Throwable e) {
System.err.println("Error loading state file: " + e.getMessage());
return 2;
}
try (Manager m = manager) {
try {
m.checkAccountState();
} catch (AuthorizationFailedException e) {
if (!"register".equals(ns.getString("command"))) {
// Register command should still be possible, if current authorization fails
System.err.println("Authorization failed, was the number registered elsewhere?");
return 2;
}
ts = m;
} catch (IOException e) {
System.err.println("Error while checking account: " + e.getMessage());
return 2;
}
}
String commandKey = ns.getString("command");
final Map<String, Command> commands = Commands.getCommands();
if (commands.containsKey(commandKey)) {
Command command = commands.get(commandKey);
if (dBusConn != null) {
if (command instanceof ExtendedDbusCommand) {
return ((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn);
} else if (command instanceof DbusCommand) {
return ((DbusCommand) command).handleCommand(ns, ts);
} else {
System.err.println(commandKey + " is not yet implemented via dbus");
return 1;
}
} else {
if (command instanceof LocalCommand) {
return ((LocalCommand) command).handleCommand(ns, m);
} else if (command instanceof ProvisioningCommand) {
return ((ProvisioningCommand) command).handleCommand(ns, pm);
} else if (command instanceof DbusCommand) {
return ((DbusCommand) command).handleCommand(ns, ts);
} else {
System.err.println(commandKey + " is only works via dbus");
return 1;
}
}
}
return 0;
} finally {
if (dBusConn != null) {
dBusConn.disconnect();
return handleCommands(ns, m);
} catch (IOException e) {
e.printStackTrace();
return 3;
}
}
}
private static int handleCommands(Namespace ns, Signal ts, DBusConnection dBusConn) {
String commandKey = ns.getString("command");
final Map<String, Command> commands = Commands.getCommands();
if (commands.containsKey(commandKey)) {
Command command = commands.get(commandKey);
if (command instanceof ExtendedDbusCommand) {
return ((ExtendedDbusCommand) command).handleCommand(ns, ts, dBusConn);
} else if (command instanceof DbusCommand) {
return ((DbusCommand) command).handleCommand(ns, ts);
} else {
System.err.println(commandKey + " is not yet implemented via dbus");
return 1;
}
}
return 0;
}
private static int handleCommands(Namespace ns, ProvisioningManager pm) {
String commandKey = ns.getString("command");
final Map<String, Command> commands = Commands.getCommands();
if (commands.containsKey(commandKey)) {
Command command = commands.get(commandKey);
if (command instanceof ProvisioningCommand) {
return ((ProvisioningCommand) command).handleCommand(ns, pm);
} else {
System.err.println(commandKey + " only works with a username");
return 1;
}
}
return 0;
}
private static int handleCommands(Namespace ns, Manager m) {
String commandKey = ns.getString("command");
final Map<String, Command> commands = Commands.getCommands();
if (commands.containsKey(commandKey)) {
Command command = commands.get(commandKey);
if (command instanceof LocalCommand) {
return ((LocalCommand) command).handleCommand(ns, m);
} else if (command instanceof DbusCommand) {
return ((DbusCommand) command).handleCommand(ns, m);
} else if (command instanceof ExtendedDbusCommand) {
System.err.println(commandKey + " only works via dbus");
}
return 1;
}
return 0;
}
/**
* Uses $XDG_DATA_HOME/signal-cli if it exists, or if none of the legacy directories exist:
* - $HOME/.config/signal