diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java index 91aece926..8957706f7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java @@ -129,10 +129,6 @@ public abstract class BriarActivity extends BaseActivity { lockManager.onActivityStop(); } - protected boolean signedIn() { - return briarController.accountSignedIn(); - } - /** * Sets the transition animations. * diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/AddContactViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/AddContactViewModel.java index 3e665d19f..4d31de63a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/AddContactViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/AddContactViewModel.java @@ -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 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) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java index 95dc0265f..55b2f6806 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/remote/PendingContactListViewModel.java @@ -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> 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) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbController.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbController.java index 8f9fc3be1..8e2078597 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbController.java @@ -2,6 +2,7 @@ package org.briarproject.briar.android.controller; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +@Deprecated @NotNullByDefault public interface DbController { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java index 5899697ef..b77ad0995 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/DbControllerImpl.java @@ -11,6 +11,7 @@ import javax.annotation.concurrent.Immutable; import javax.inject.Inject; @Immutable +@Deprecated @NotNullByDefault public class DbControllerImpl implements DbController { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index db32a1914..9c372a112 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -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(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java index 8e65db26c..92ed61622 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java @@ -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) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageViewModel.java index 1a59b02bf..904421754 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ImageViewModel.java @@ -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> receivedAttachments = - new HashMap<>(); + private final HashMap> + 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()); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java index c354e0f66..731e62d46 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java @@ -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 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); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java index cc2c5ef7f..3dbc9c517 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewModel.java @@ -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); } } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java new file mode 100644 index 000000000..33881a725 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java @@ -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(); + } + }); + } + +}