1 package org
.asamk
.signal
.dbus
;
3 import org
.asamk
.Signal
;
4 import org
.asamk
.SignalControl
;
5 import org
.asamk
.signal
.DbusConfig
;
6 import org
.asamk
.signal
.commands
.Command
;
7 import org
.asamk
.signal
.commands
.CommandHandler
;
8 import org
.asamk
.signal
.commands
.LocalCommand
;
9 import org
.asamk
.signal
.commands
.MultiLocalCommand
;
10 import org
.asamk
.signal
.commands
.ProvisioningCommand
;
11 import org
.asamk
.signal
.commands
.RegistrationCommand
;
12 import org
.asamk
.signal
.commands
.exceptions
.CommandException
;
13 import org
.asamk
.signal
.commands
.exceptions
.UnexpectedErrorException
;
14 import org
.asamk
.signal
.commands
.exceptions
.UserErrorException
;
15 import org
.freedesktop
.dbus
.connections
.impl
.DBusConnection
;
16 import org
.freedesktop
.dbus
.errors
.UnknownMethod
;
17 import org
.freedesktop
.dbus
.exceptions
.DBusException
;
18 import org
.freedesktop
.dbus
.exceptions
.DBusExecutionException
;
20 public class DbusCommandHandler
{
22 public static void handleCommand(
23 final Command command
,
25 final DBusConnection dBusConn
,
26 final CommandHandler commandHandler
27 ) throws CommandException
, DBusException
{
29 if (command
instanceof ProvisioningCommand c
) {
30 if (account
!= null) {
31 throw new UserErrorException("You cannot specify a account (phone number) when linking");
34 handleProvisioningCommand(c
, dBusConn
, commandHandler
);
38 if (account
== null && command
instanceof MultiLocalCommand c
) {
39 handleMultiLocalCommand(c
, dBusConn
, commandHandler
);
42 if (account
!= null && command
instanceof RegistrationCommand c
) {
43 handleRegistrationCommand(c
, account
, dBusConn
, commandHandler
);
46 if (!(command
instanceof LocalCommand localCommand
)) {
47 throw new UserErrorException("Command only works in multi-account mode");
50 var accountObjectPath
= account
== null ?
tryGetSingleAccountObjectPath(dBusConn
) : null;
51 if (accountObjectPath
== null) {
52 accountObjectPath
= DbusConfig
.getObjectPath(account
);
54 handleLocalCommand(localCommand
, accountObjectPath
, dBusConn
, commandHandler
);
55 } catch (UnsupportedOperationException e
) {
56 throw new UserErrorException("Command is not yet implemented via dbus", e
);
57 } catch (DBusExecutionException e
) {
58 throw new UnexpectedErrorException(e
.getMessage(), e
);
62 private static String
tryGetSingleAccountObjectPath(final DBusConnection dBusConn
) throws DBusException
, CommandException
{
63 var control
= dBusConn
.getRemoteObject(DbusConfig
.getBusname(),
64 DbusConfig
.getObjectPath(),
67 final var accounts
= control
.listAccounts();
68 if (accounts
.isEmpty()) {
69 throw new UserErrorException("No local users found, you first need to register or link an account");
70 } else if (accounts
.size() > 1) {
71 throw new UserErrorException(
72 "Multiple users found, you need to specify an account (phone number) with -a");
75 return accounts
.get(0).getPath();
76 } catch (UnknownMethod e
) {
77 // dbus daemon not running in multi-account mode
82 private static void handleMultiLocalCommand(
83 final MultiLocalCommand c
, final DBusConnection dBusConn
, final CommandHandler commandHandler
84 ) throws CommandException
, DBusException
{
85 final var signalControl
= dBusConn
.getRemoteObject(DbusConfig
.getBusname(),
86 DbusConfig
.getObjectPath(),
88 try (final var multiAccountManager
= new DbusMultiAccountManagerImpl(signalControl
, dBusConn
)) {
89 commandHandler
.handleMultiLocalCommand(c
, multiAccountManager
);
93 private static void handleLocalCommand(
95 String accountObjectPath
,
96 final DBusConnection dBusConn
,
97 final CommandHandler commandHandler
98 ) throws CommandException
, DBusException
{
99 var signal
= dBusConn
.getRemoteObject(DbusConfig
.getBusname(), accountObjectPath
, Signal
.class);
100 try (final var manager
= new DbusManagerImpl(signal
, dBusConn
)) {
101 commandHandler
.handleLocalCommand(c
, manager
);
105 private static void handleRegistrationCommand(
106 final RegistrationCommand c
,
108 final DBusConnection dBusConn
,
109 final CommandHandler commandHandler
111 ) throws CommandException
, DBusException
{
112 final var signalControl
= dBusConn
.getRemoteObject(DbusConfig
.getBusname(),
113 DbusConfig
.getObjectPath(),
114 SignalControl
.class);
115 try (final var registrationManager
= new DbusRegistrationManagerImpl(account
, signalControl
, dBusConn
)) {
116 commandHandler
.handleRegistrationCommand(c
, registrationManager
);
120 private static void handleProvisioningCommand(
121 final ProvisioningCommand c
, final DBusConnection dBusConn
, final CommandHandler commandHandler
123 ) throws CommandException
, DBusException
{
124 final var signalControl
= dBusConn
.getRemoteObject(DbusConfig
.getBusname(),
125 DbusConfig
.getObjectPath(),
126 SignalControl
.class);
127 final var provisioningManager
= new DbusProvisioningManagerImpl(signalControl
, dBusConn
);
128 commandHandler
.handleProvisioningCommand(c
, provisioningManager
);