mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Remove ListenableFutureTask and replace it with LiveData
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package org.briarproject.briar.android.contact;
|
||||
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
@@ -72,8 +75,6 @@ import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
||||
import org.thoughtcrime.securesms.components.util.FutureTaskListener;
|
||||
import org.thoughtcrime.securesms.components.util.ListenableFutureTask;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -81,13 +82,10 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import de.hdodenhof.circleimageview.CircleImageView;
|
||||
@@ -141,18 +139,6 @@ public class ConversationActivity extends BriarActivity
|
||||
private BriarRecyclerView list;
|
||||
private TextInputView textInputView;
|
||||
|
||||
private final ListenableFutureTask<String> contactNameTask =
|
||||
new ListenableFutureTask<>(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
Contact c = contactManager.getContact(contactId);
|
||||
contactName = c.getAuthor().getName();
|
||||
return c.getAuthor().getName();
|
||||
}
|
||||
});
|
||||
private final AtomicBoolean contactNameTaskStarted =
|
||||
new AtomicBoolean(false);
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject
|
||||
volatile ContactManager contactManager;
|
||||
@@ -177,11 +163,10 @@ public class ConversationActivity extends BriarActivity
|
||||
|
||||
private volatile ContactId contactId;
|
||||
@Nullable
|
||||
private volatile String contactName;
|
||||
@Nullable
|
||||
private volatile AuthorId contactAuthorId;
|
||||
@Nullable
|
||||
private volatile GroupId messagingGroupId;
|
||||
private MutableLiveData<String> contactName = new MutableLiveData<>();
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
@@ -292,7 +277,7 @@ public class ConversationActivity extends BriarActivity
|
||||
long start = now();
|
||||
if (contactName == null || contactAuthorId == null) {
|
||||
Contact contact = contactManager.getContact(contactId);
|
||||
contactName = contact.getAuthor().getName();
|
||||
contactName.postValue(contact.getAuthor().getName());
|
||||
contactAuthorId = contact.getAuthor().getId();
|
||||
}
|
||||
logDuration(LOG, "Loading contact", start);
|
||||
@@ -306,12 +291,13 @@ public class ConversationActivity extends BriarActivity
|
||||
});
|
||||
}
|
||||
|
||||
// contactAuthorId and contactName are expected to be set
|
||||
private void displayContactDetails() {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
//noinspection ConstantConditions
|
||||
toolbarAvatar.setImageDrawable(
|
||||
new IdenticonDrawable(contactAuthorId.getBytes()));
|
||||
toolbarTitle.setText(contactName);
|
||||
toolbarTitle.setText(contactName.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -381,13 +367,13 @@ public class ConversationActivity extends BriarActivity
|
||||
ConversationItem item;
|
||||
if (h instanceof IntroductionResponse) {
|
||||
IntroductionResponse i = (IntroductionResponse) h;
|
||||
item = ConversationItem.from(this, contactName, i);
|
||||
item = ConversationItem.from(this, contactName.getValue(), i);
|
||||
} else if (h instanceof PrivateRequest) {
|
||||
PrivateRequest r = (PrivateRequest) h;
|
||||
item = ConversationItem.from(this, contactName, r);
|
||||
item = ConversationItem.from(this, contactName.getValue(), r);
|
||||
} else if (h instanceof PrivateResponse) {
|
||||
PrivateResponse r = (PrivateResponse) h;
|
||||
item = ConversationItem.from(this, contactName, r);
|
||||
item = ConversationItem.from(this, contactName.getValue(), r);
|
||||
} else {
|
||||
item = ConversationItem.from(h);
|
||||
String body = bodyCache.get(h.getId());
|
||||
@@ -480,43 +466,42 @@ public class ConversationActivity extends BriarActivity
|
||||
}
|
||||
|
||||
private void onNewPrivateMessage(PrivateMessageHeader h) {
|
||||
if (h instanceof PrivateRequest || h instanceof PrivateResponse) {
|
||||
getContactNameTask().addListener(new FutureTaskListener<String>() {
|
||||
@Override
|
||||
public void onSuccess(String contactName) {
|
||||
runOnUiThreadUnlessDestroyed(
|
||||
() -> handlePrivateRequestAndResponse(h,
|
||||
contactName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable exception) {
|
||||
runOnUiThreadUnlessDestroyed(
|
||||
() -> handleDbException((DbException) exception));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
addConversationItem(ConversationItem.from(h));
|
||||
loadMessageBody(h.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void handlePrivateRequestAndResponse(PrivateMessageHeader h,
|
||||
String contactName) {
|
||||
ConversationItem item;
|
||||
if (h instanceof PrivateRequest) {
|
||||
PrivateRequest m = (PrivateRequest) h;
|
||||
item = ConversationItem
|
||||
.from(ConversationActivity.this, contactName, m);
|
||||
} else if (h instanceof PrivateResponse) {
|
||||
PrivateResponse m = (PrivateResponse) h;
|
||||
item = ConversationItem
|
||||
.from(ConversationActivity.this, contactName, m);
|
||||
} else {
|
||||
throw new AssertionError("Unknown PrivateMessageHeader");
|
||||
}
|
||||
addConversationItem(item);
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
if (h instanceof PrivateRequest) {
|
||||
contactName.observe(this, new Observer<String>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable String name) {
|
||||
if (name == null) loadContactName();
|
||||
else {
|
||||
PrivateRequest m = (PrivateRequest) h;
|
||||
ConversationItem item = ConversationItem.from(
|
||||
ConversationActivity.this, name, m);
|
||||
addConversationItem(item);
|
||||
contactName.removeObserver(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (contactName.getValue() == null) loadContactName();
|
||||
} else if (h instanceof PrivateResponse) {
|
||||
contactName.observe(this, new Observer<String>() {
|
||||
@Override
|
||||
public void onChanged(@Nullable String name) {
|
||||
if (name == null) loadContactName();
|
||||
else {
|
||||
PrivateResponse m = (PrivateResponse) h;
|
||||
ConversationItem item = ConversationItem.from(
|
||||
ConversationActivity.this, name, m);
|
||||
addConversationItem(item);
|
||||
contactName.removeObserver(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (contactName.getValue() == null) loadContactName();
|
||||
} else {
|
||||
addConversationItem(ConversationItem.from(h));
|
||||
loadMessageBody(h.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void markMessages(Collection<MessageId> messageIds, boolean sent,
|
||||
@@ -804,10 +789,15 @@ public class ConversationActivity extends BriarActivity
|
||||
groupInvitationManager.respondToInvitation(contactId, id, accept);
|
||||
}
|
||||
|
||||
private ListenableFutureTask<String> getContactNameTask() {
|
||||
if (!contactNameTaskStarted.getAndSet(true))
|
||||
runOnDbThread(contactNameTask);
|
||||
return contactNameTask;
|
||||
private void loadContactName() {
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
Contact c = contactManager.getContact(contactId);
|
||||
contactName.postValue(c.getAuthor().getName());
|
||||
} catch (DbException e) {
|
||||
handleDbException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.components.util;
|
||||
|
||||
public interface FutureTaskListener<V> {
|
||||
void onSuccess(V result);
|
||||
|
||||
void onFailure(Throwable error);
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Open Whisper Systems
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.thoughtcrime.securesms.components.util;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ListenableFutureTask<V> extends FutureTask<V> {
|
||||
|
||||
private final List<FutureTaskListener<V>> listeners = new LinkedList<>();
|
||||
|
||||
@Nullable
|
||||
private final Object identifier;
|
||||
|
||||
public ListenableFutureTask(Callable<V> callable) {
|
||||
this(callable, null);
|
||||
}
|
||||
|
||||
private ListenableFutureTask(Callable<V> callable,
|
||||
@Nullable Object identifier) {
|
||||
super(callable);
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public ListenableFutureTask(V result) {
|
||||
this(result, null);
|
||||
}
|
||||
|
||||
private ListenableFutureTask(V result, @Nullable Object identifier) {
|
||||
super(() -> result);
|
||||
this.identifier = identifier;
|
||||
this.run();
|
||||
}
|
||||
|
||||
public synchronized void addListener(FutureTaskListener<V> listener) {
|
||||
if (this.isDone()) {
|
||||
callback(listener);
|
||||
} else {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void removeListener(FutureTaskListener<V> listener) {
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void done() {
|
||||
callback();
|
||||
}
|
||||
|
||||
private void callback() {
|
||||
for (FutureTaskListener<V> listener : listeners) {
|
||||
callback(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private void callback(FutureTaskListener<V> listener) {
|
||||
if (listener != null) {
|
||||
try {
|
||||
listener.onSuccess(get());
|
||||
} catch (InterruptedException e) {
|
||||
throw new AssertionError(e);
|
||||
} catch (ExecutionException e) {
|
||||
listener.onFailure(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other != null && other instanceof ListenableFutureTask &&
|
||||
this.identifier != null) {
|
||||
return identifier.equals(other);
|
||||
} else {
|
||||
return super.equals(other);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (identifier != null) return identifier.hashCode();
|
||||
else return super.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user