BookmarkManager.java

  1package eu.siacs.conversations.xmpp.manager;
  2
  3import android.text.TextUtils;
  4import android.util.Log;
  5import androidx.annotation.NonNull;
  6import com.google.common.util.concurrent.FutureCallback;
  7import com.google.common.util.concurrent.Futures;
  8import com.google.common.util.concurrent.ListenableFuture;
  9import com.google.common.util.concurrent.MoreExecutors;
 10import eu.siacs.conversations.Config;
 11import eu.siacs.conversations.entities.Account;
 12import eu.siacs.conversations.entities.Bookmark;
 13import eu.siacs.conversations.entities.Conversation;
 14import eu.siacs.conversations.entities.MucOptions;
 15import eu.siacs.conversations.services.XmppConnectionService;
 16import eu.siacs.conversations.xmpp.XmppConnection;
 17
 18public class BookmarkManager extends AbstractManager {
 19
 20    private final XmppConnectionService service;
 21
 22    public BookmarkManager(final XmppConnectionService service, final XmppConnection connection) {
 23        super(service, connection);
 24        this.service = service;
 25    }
 26
 27    public void request() {
 28        if (getManager(NativeBookmarkManager.class).hasFeature()) {
 29            getManager(NativeBookmarkManager.class).fetch();
 30        } else if (getManager(LegacyBookmarkManager.class).hasConversion()) {
 31            final var account = getAccount();
 32            Log.d(
 33                    Config.LOGTAG,
 34                    account.getJid() + ": not fetching bookmarks. waiting for server to push");
 35        } else {
 36            getManager(PrivateStorageManager.class).fetchBookmarks();
 37        }
 38    }
 39
 40    public void save(final Conversation conversation, final String name) {
 41        final Account account = conversation.getAccount();
 42        final Bookmark bookmark = new Bookmark(account, conversation.getJid().asBareJid());
 43        final String nick = conversation.getJid().getResource();
 44        if (nick != null && !nick.isEmpty() && !nick.equals(MucOptions.defaultNick(account))) {
 45            bookmark.setNick(nick);
 46        }
 47        if (!TextUtils.isEmpty(name)) {
 48            bookmark.setBookmarkName(name);
 49        }
 50        bookmark.setAutojoin(true);
 51        this.create(bookmark);
 52        bookmark.setConversation(conversation);
 53    }
 54
 55    public void create(final Bookmark bookmark) {
 56        final var account = getAccount();
 57        account.putBookmark(bookmark);
 58        final ListenableFuture<Void> future;
 59        if (getManager(NativeBookmarkManager.class).hasFeature()) {
 60            future = getManager(NativeBookmarkManager.class).publish(bookmark);
 61        } else if (getManager(LegacyBookmarkManager.class).hasConversion()) {
 62            future = getManager(LegacyBookmarkManager.class).publish(account.getBookmarks());
 63        } else {
 64            future =
 65                    getManager(PrivateStorageManager.class)
 66                            .publishBookmarks(account.getBookmarks());
 67        }
 68        Futures.addCallback(
 69                future,
 70                new FutureCallback<>() {
 71                    @Override
 72                    public void onSuccess(Void result) {
 73                        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": created bookmark");
 74                    }
 75
 76                    @Override
 77                    public void onFailure(@NonNull Throwable t) {
 78                        Log.d(
 79                                Config.LOGTAG,
 80                                account.getJid().asBareJid() + ": could not create bookmark",
 81                                t);
 82                    }
 83                },
 84                MoreExecutors.directExecutor());
 85    }
 86
 87    public void delete(final Bookmark bookmark) {
 88        final var account = getAccount();
 89        account.removeBookmark(bookmark);
 90        final ListenableFuture<Void> future;
 91        if (getManager(NativeBookmarkManager.class).hasFeature()) {
 92            future = getManager(NativeBookmarkManager.class).retract(bookmark.getJid().asBareJid());
 93        } else if (getManager(LegacyBookmarkManager.class).hasConversion()) {
 94            future = getManager(LegacyBookmarkManager.class).publish(account.getBookmarks());
 95        } else {
 96            future =
 97                    getManager(PrivateStorageManager.class)
 98                            .publishBookmarks(account.getBookmarks());
 99        }
100        Futures.addCallback(
101                future,
102                new FutureCallback<>() {
103                    @Override
104                    public void onSuccess(Void result) {
105                        Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": deleted bookmark");
106                    }
107
108                    @Override
109                    public void onFailure(@NonNull Throwable t) {
110                        Log.d(
111                                Config.LOGTAG,
112                                account.getJid().asBareJid() + ": could not delete bookmark",
113                                t);
114                    }
115                },
116                MoreExecutors.directExecutor());
117    }
118
119    public void ensureBookmarkIsAutoJoin(final Conversation conversation) {
120        final var account = getAccount();
121        final var existingBookmark = conversation.getBookmark();
122        if (existingBookmark == null) {
123            final var bookmark = new Bookmark(account, conversation.getJid().asBareJid());
124            bookmark.setAutojoin(true);
125            create(bookmark);
126        } else {
127            if (existingBookmark.autojoin()) {
128                return;
129            }
130            existingBookmark.setAutojoin(true);
131            create(existingBookmark);
132        }
133    }
134
135    public void processModifiedBookmark(final Bookmark bookmark, final boolean pep) {
136        final var existing = this.service.find(bookmark);
137        if (existing != null) {
138            if (existing.getMode() != Conversation.MODE_MULTI) {
139                return;
140            }
141            bookmark.setConversation(existing);
142            if (pep && !bookmark.autojoin()) {
143                Log.d(
144                        Config.LOGTAG,
145                        getAccount().getJid().asBareJid()
146                                + ": archiving conference ("
147                                + existing.getJid()
148                                + ") after receiving pep");
149                service.archiveConversation(existing, false);
150            } else {
151                final MucOptions mucOptions = existing.getMucOptions();
152                if (mucOptions.getError() == MucOptions.Error.NICK_IN_USE) {
153                    final String current = mucOptions.getActualNick();
154                    final String proposed = mucOptions.getProposedNickPure();
155                    if (current != null && !current.equals(proposed)) {
156                        Log.d(
157                                Config.LOGTAG,
158                                getAccount().getJid().asBareJid()
159                                        + ": proposed nick changed after bookmark push "
160                                        + current
161                                        + "->"
162                                        + proposed);
163                        getManager(MultiUserChatManager.class).join(existing);
164                    }
165                } else {
166                    getManager(MultiUserChatManager.class).checkMucRequiresRename(existing);
167                }
168            }
169        } else if (bookmark.autojoin()) {
170            final var fresh =
171                    this.service.findOrCreateConversation(
172                            getAccount(), bookmark.getFullJid(), true, true, false);
173            bookmark.setConversation(fresh);
174        }
175    }
176}