Merge branch '1800-db-view-model' into 'master'

Introduce DbViewModel as replacement of DbController

See merge request briar/briar!1326
This commit is contained in:
akwizgran
2021-01-04 14:00:42 +00:00
11 changed files with 114 additions and 80 deletions

View File

@@ -129,10 +129,6 @@ public abstract class BriarActivity extends BaseActivity {
lockManager.onActivityStop();
}
protected boolean signedIn() {
return briarController.accountSignedIn();
}
/**
* Sets the transition animations.
*

View File

@@ -9,7 +9,9 @@ import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.NoSuchPendingContactException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.LiveResult;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
@@ -21,7 +23,6 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -31,14 +32,12 @@ import static org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_R
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class AddContactViewModel extends AndroidViewModel {
public class AddContactViewModel extends DbViewModel {
private final static Logger LOG =
getLogger(AddContactViewModel.class.getName());
private final ContactManager contactManager;
@DatabaseExecutor
private final Executor dbExecutor;
private final MutableLiveData<String> handshakeLink =
new MutableLiveData<>();
@@ -52,10 +51,10 @@ public class AddContactViewModel extends AndroidViewModel {
@Inject
AddContactViewModel(Application application,
ContactManager contactManager,
@DatabaseExecutor Executor dbExecutor) {
super(application);
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager) {
super(application, dbExecutor, lifecycleManager);
this.contactManager = contactManager;
this.dbExecutor = dbExecutor;
}
void onCreate() {
@@ -63,7 +62,7 @@ public class AddContactViewModel extends AndroidViewModel {
}
private void loadHandshakeLink() {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
handshakeLink.postValue(contactManager.getHandshakeLink());
} catch (DbException e) {
@@ -102,7 +101,7 @@ public class AddContactViewModel extends AndroidViewModel {
void addContact(String nickname) {
if (remoteHandshakeLink == null) throw new IllegalStateException();
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
contactManager.addPendingContact(remoteHandshakeLink, nickname);
addContactResult.postValue(new LiveResult<>(true));
@@ -122,11 +121,11 @@ public class AddContactViewModel extends AndroidViewModel {
}
public void updatePendingContact(String name, PendingContact p) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
contactManager.removePendingContact(p.getId());
addContact(name);
} catch(NoSuchPendingContactException e) {
} catch (NoSuchPendingContactException e) {
logException(LOG, WARNING, e);
// no error in UI as pending contact was converted into contact
} catch (DbException e) {

View File

@@ -14,9 +14,11 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.rendezvous.RendezvousPoller;
import org.briarproject.bramble.api.rendezvous.event.RendezvousPollEvent;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import java.util.ArrayList;
import java.util.Collection;
@@ -26,7 +28,6 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -36,14 +37,12 @@ import static org.briarproject.bramble.api.contact.PendingContactState.OFFLINE;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class PendingContactListViewModel extends AndroidViewModel
public class PendingContactListViewModel extends DbViewModel
implements EventListener {
private final Logger LOG =
getLogger(PendingContactListViewModel.class.getName());
@DatabaseExecutor
private final Executor dbExecutor;
private final ContactManager contactManager;
private final RendezvousPoller rendezvousPoller;
private final EventBus eventBus;
@@ -56,11 +55,11 @@ public class PendingContactListViewModel extends AndroidViewModel
@Inject
PendingContactListViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
ContactManager contactManager,
RendezvousPoller rendezvousPoller,
EventBus eventBus) {
super(application);
this.dbExecutor = dbExecutor;
super(application, dbExecutor, lifecycleManager);
this.contactManager = contactManager;
this.rendezvousPoller = rendezvousPoller;
this.eventBus = eventBus;
@@ -87,7 +86,7 @@ public class PendingContactListViewModel extends AndroidViewModel
}
private void loadPendingContacts() {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Collection<Pair<PendingContact, PendingContactState>> pairs =
contactManager.getPendingContacts();
@@ -113,7 +112,7 @@ public class PendingContactListViewModel extends AndroidViewModel
}
void removePendingContact(PendingContactId id) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
contactManager.removePendingContact(id);
} catch (DbException e) {

View File

@@ -2,6 +2,7 @@ package org.briarproject.briar.android.controller;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@Deprecated
@NotNullByDefault
public interface DbController {

View File

@@ -11,6 +11,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject;
@Immutable
@Deprecated
@NotNullByDefault
public class DbControllerImpl implements DbController {

View File

@@ -98,7 +98,6 @@ import androidx.core.content.ContextCompat;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.selection.Selection;
import androidx.recyclerview.selection.SelectionPredicates;
import androidx.recyclerview.selection.SelectionTracker;
@@ -224,8 +223,9 @@ public class ConversationActivity extends BriarActivity
if (id == -1) throw new IllegalStateException();
contactId = new ContactId(id);
viewModel = ViewModelProviders.of(this, viewModelFactory)
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ConversationViewModel.class);
viewModel.setContactId(contactId);
attachmentRetriever = viewModel.getAttachmentRetriever();
setContentView(R.layout.activity_conversation);
@@ -330,16 +330,6 @@ public class ConversationActivity extends BriarActivity
list.startPeriodicUpdate();
}
@Override
public void onResume() {
super.onResume();
// Trigger loading of contact data, noop if data was loaded already.
//
// We can only start loading data *after* we are sure
// the user has signed in. After sign-in, onCreate() isn't run again.
if (signedIn()) viewModel.setContactId(contactId);
}
@Override
public void onStop() {
super.onStop();

View File

@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.identity.AuthorId;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.SettingsManager;
@@ -26,6 +27,7 @@ import org.briarproject.briar.android.attachment.AttachmentManager;
import org.briarproject.briar.android.attachment.AttachmentResult;
import org.briarproject.briar.android.attachment.AttachmentRetriever;
import org.briarproject.briar.android.util.UiUtils;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
import org.briarproject.briar.api.messaging.AttachmentHeader;
@@ -44,7 +46,6 @@ import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
@@ -59,10 +60,10 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
@NotNullByDefault
public class ConversationViewModel extends AndroidViewModel
public class ConversationViewModel extends DbViewModel
implements EventListener, AttachmentManager {
private static Logger LOG =
private static final Logger LOG =
getLogger(ConversationViewModel.class.getName());
private static final String SHOW_ONBOARDING_IMAGE =
@@ -70,8 +71,6 @@ public class ConversationViewModel extends AndroidViewModel
private static final String SHOW_ONBOARDING_INTRODUCTION =
"showOnboardingIntroduction";
@DatabaseExecutor
private final Executor dbExecutor;
private final TransactionManager db;
private final EventBus eventBus;
private final MessagingManager messagingManager;
@@ -105,6 +104,7 @@ public class ConversationViewModel extends AndroidViewModel
@Inject
ConversationViewModel(Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
TransactionManager db,
EventBus eventBus,
MessagingManager messagingManager,
@@ -113,8 +113,7 @@ public class ConversationViewModel extends AndroidViewModel
PrivateMessageFactory privateMessageFactory,
AttachmentRetriever attachmentRetriever,
AttachmentCreator attachmentCreator) {
super(application);
this.dbExecutor = dbExecutor;
super(application, dbExecutor, lifecycleManager);
this.db = db;
this.eventBus = eventBus;
this.messagingManager = messagingManager;
@@ -143,7 +142,7 @@ public class ConversationViewModel extends AndroidViewModel
AttachmentReceivedEvent a = (AttachmentReceivedEvent) e;
if (a.getContactId().equals(contactId)) {
LOG.info("Attachment received");
dbExecutor.execute(() -> attachmentRetriever
runOnDbThread(() -> attachmentRetriever
.loadAttachmentItem(a.getMessageId()));
}
}
@@ -163,7 +162,7 @@ public class ConversationViewModel extends AndroidViewModel
}
private void loadContact(ContactId contactId) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
long start = now();
Contact c = contactManager.getContact(contactId);
@@ -181,7 +180,7 @@ public class ConversationViewModel extends AndroidViewModel
}
void markMessageRead(GroupId g, MessageId m) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
long start = now();
messagingManager.setReadFlag(g, m, true);
@@ -193,7 +192,7 @@ public class ConversationViewModel extends AndroidViewModel
}
void setContactAlias(String alias) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
contactManager.setContactAlias(requireNonNull(contactId),
alias.isEmpty() ? null : alias);
@@ -296,7 +295,7 @@ public class ConversationViewModel extends AndroidViewModel
@UiThread
private void storeMessage(PrivateMessage m) {
attachmentCreator.onAttachmentsSent(m.getMessage().getId());
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
long start = now();
messagingManager.addLocalMessage(m);
@@ -356,7 +355,7 @@ public class ConversationViewModel extends AndroidViewModel
@UiThread
void recheckFeaturesAndOnboarding(ContactId contactId) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
checkFeaturesAndOnboarding(contactId);
} catch (DbException e) {

View File

@@ -11,9 +11,11 @@ import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.lifecycle.IoExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.android.attachment.AttachmentItem;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
import org.briarproject.briar.api.messaging.Attachment;
@@ -37,7 +39,6 @@ import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.lifecycle.AndroidViewModel;
import static android.media.MediaScannerConnection.scanFile;
import static android.os.Environment.DIRECTORY_PICTURES;
@@ -49,20 +50,18 @@ import static org.briarproject.bramble.util.IoUtils.copyAndClose;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class ImageViewModel extends AndroidViewModel implements EventListener {
public class ImageViewModel extends DbViewModel implements EventListener {
private static Logger LOG = getLogger(ImageViewModel.class.getName());
private static final Logger LOG = getLogger(ImageViewModel.class.getName());
private final MessagingManager messagingManager;
private final EventBus eventBus;
@DatabaseExecutor
private final Executor dbExecutor;
@IoExecutor
private final Executor ioExecutor;
private boolean receivedAttachmentsInitialized = false;
private HashMap<MessageId, MutableLiveEvent<Boolean>> receivedAttachments =
new HashMap<>();
private final HashMap<MessageId, MutableLiveEvent<Boolean>>
receivedAttachments = new HashMap<>();
/**
* true means there was an error saving the image, false if image was saved.
@@ -75,13 +74,14 @@ public class ImageViewModel extends AndroidViewModel implements EventListener {
@Inject
ImageViewModel(Application application,
MessagingManager messagingManager, EventBus eventBus,
MessagingManager messagingManager,
EventBus eventBus,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
@IoExecutor Executor ioExecutor) {
super(application);
super(application, dbExecutor, lifecycleManager);
this.messagingManager = messagingManager;
this.eventBus = eventBus;
this.dbExecutor = dbExecutor;
this.ioExecutor = ioExecutor;
eventBus.addListener(this);
@@ -195,7 +195,7 @@ public class ImageViewModel extends AndroidViewModel implements EventListener {
private void saveImage(AttachmentItem attachment, OutputStreamProvider osp,
@Nullable Runnable afterCopy) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Attachment a =
messagingManager.getAttachment(attachment.getHeader());

View File

@@ -4,9 +4,11 @@ import android.app.Application;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -14,7 +16,6 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.UiThread;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -28,7 +29,7 @@ import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
@NotNullByDefault
public class NavDrawerViewModel extends AndroidViewModel {
public class NavDrawerViewModel extends DbViewModel {
private static final Logger LOG =
getLogger(NavDrawerViewModel.class.getName());
@@ -37,8 +38,6 @@ public class NavDrawerViewModel extends AndroidViewModel {
private static final String SHOW_TRANSPORTS_ONBOARDING =
"showTransportsOnboarding";
@DatabaseExecutor
private final Executor dbExecutor;
private final SettingsManager settingsManager;
private final MutableLiveData<Boolean> showExpiryWarning =
@@ -49,10 +48,11 @@ public class NavDrawerViewModel extends AndroidViewModel {
new MutableLiveData<>();
@Inject
NavDrawerViewModel(Application app, @DatabaseExecutor Executor dbExecutor,
NavDrawerViewModel(Application app,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
SettingsManager settingsManager) {
super(app);
this.dbExecutor = dbExecutor;
super(app, dbExecutor, lifecycleManager);
this.settingsManager = settingsManager;
}
@@ -62,7 +62,7 @@ public class NavDrawerViewModel extends AndroidViewModel {
@UiThread
void checkExpiryWarning() {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Settings settings =
settingsManager.getSettings(SETTINGS_NAMESPACE);
@@ -97,7 +97,7 @@ public class NavDrawerViewModel extends AndroidViewModel {
@UiThread
void expiryWarningDismissed() {
showExpiryWarning.setValue(false);
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Settings settings = new Settings();
int date = (int) (System.currentTimeMillis() / 1000L);
@@ -120,7 +120,7 @@ public class NavDrawerViewModel extends AndroidViewModel {
shouldAskForDozeWhitelisting.setValue(false);
return;
}
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Settings settings =
settingsManager.getSettings(SETTINGS_NAMESPACE);
@@ -141,7 +141,7 @@ public class NavDrawerViewModel extends AndroidViewModel {
@UiThread
void checkTransportsOnboarding() {
if (showTransportsOnboarding.getValue() != null) return;
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Settings settings =
settingsManager.getSettings(SETTINGS_NAMESPACE);
@@ -157,7 +157,7 @@ public class NavDrawerViewModel extends AndroidViewModel {
@UiThread
void transportsOnboardingShown() {
showTransportsOnboarding.setValue(false);
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
Settings settings = new Settings();
settings.putBoolean(SHOW_TRANSPORTS_ONBOARDING, false);

View File

@@ -12,6 +12,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.network.NetworkManager;
import org.briarproject.bramble.api.network.NetworkStatus;
import org.briarproject.bramble.api.network.event.NetworkStatusEvent;
@@ -27,6 +28,7 @@ import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
import org.briarproject.bramble.api.settings.Settings;
import org.briarproject.bramble.api.settings.SettingsManager;
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
import org.briarproject.briar.android.viewmodel.DbViewModel;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
@@ -34,7 +36,6 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
@@ -51,13 +52,12 @@ import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@NotNullByDefault
public class PluginViewModel extends AndroidViewModel implements EventListener {
public class PluginViewModel extends DbViewModel implements EventListener {
private static final Logger LOG =
getLogger(PluginViewModel.class.getName());
private final Application app;
private final Executor dbExecutor;
private final SettingsManager settingsManager;
private final PluginManager pluginManager;
private final EventBus eventBus;
@@ -85,11 +85,11 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
@Inject
PluginViewModel(Application app, @DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager,
SettingsManager settingsManager, PluginManager pluginManager,
EventBus eventBus, NetworkManager networkManager) {
super(app);
super(app, dbExecutor, lifecycleManager);
this.app = app;
this.dbExecutor = dbExecutor;
this.settingsManager = settingsManager;
this.pluginManager = pluginManager;
this.eventBus = eventBus;
@@ -182,7 +182,7 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
}
private void loadSettings() {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
boolean tor = isPluginEnabled(TorConstants.ID,
TorConstants.DEFAULT_PREF_PLUGIN_ENABLE);
@@ -219,7 +219,7 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
}
private void mergeSettings(Settings s, String namespace) {
dbExecutor.execute(() -> {
runOnDbThread(() -> {
try {
long start = now();
settingsManager.mergeSettings(s, namespace);
@@ -235,8 +235,7 @@ public class PluginViewModel extends AndroidViewModel implements EventListener {
@Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(EXTRA_STATE, 0);
if (state == STATE_ON) bluetoothTurnedOn.postValue(true);
else bluetoothTurnedOn.postValue(false);
bluetoothTurnedOn.postValue(state == STATE_ON);
}
}
}

View File

@@ -0,0 +1,50 @@
package org.briarproject.briar.android.viewmodel;
import android.app.Application;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.annotation.concurrent.Immutable;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import static java.util.logging.Logger.getLogger;
@Immutable
@NotNullByDefault
public abstract class DbViewModel extends AndroidViewModel {
private static final Logger LOG = getLogger(DbViewModel.class.getName());
@DatabaseExecutor
private final Executor dbExecutor;
private final LifecycleManager lifecycleManager;
public DbViewModel(
@NonNull Application application,
@DatabaseExecutor Executor dbExecutor,
LifecycleManager lifecycleManager) {
super(application);
this.dbExecutor = dbExecutor;
this.lifecycleManager = lifecycleManager;
}
public void runOnDbThread(Runnable task) {
dbExecutor.execute(() -> {
try {
lifecycleManager.waitForDatabase();
task.run();
} catch (InterruptedException e) {
LOG.warning("Interrupted while waiting for database");
Thread.currentThread().interrupt();
}
});
}
}