package org.mercury_im.messenger.android.ui.account.detail; import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.ui.base.MercuryAndroidViewModel; import org.mercury_im.messenger.core.SchedulersFacade; import org.mercury_im.messenger.core.util.DefaultUtil; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.account.detail.AccountDetailsViewModel; import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem; import org.pgpainless.key.OpenPgpV4Fingerprint; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; public class AndroidAccountDetailsViewModel extends AndroidViewModel implements MercuryAndroidViewModel { private static final Logger LOGGER = Logger.getLogger(AndroidAccountDetailsViewModel.class.getName()); @Inject SchedulersFacade schedulers; @Inject AccountDetailsViewModel commonViewModel; private final UUID accountId; private MutableLiveData> ikeyFingerprint = new MutableLiveData<>(); private MutableLiveData localFingerprint = new MutableLiveData<>(); private MutableLiveData> remoteFingerprints = new MutableLiveData<>(new ArrayList<>()); private MutableLiveData jid = new MutableLiveData<>(DefaultUtil.defaultJid()); private MutableLiveData accountEnabled = new MutableLiveData<>(false); private MutableLiveData accountAuthenticated = new MutableLiveData<>(false); public AndroidAccountDetailsViewModel(@NonNull Application application, UUID accountId) { super(application); this.accountId = accountId; LOGGER.log(Level.INFO, "Creating AndroidAccountDetailsViewModel"); ((MercuryImApplication) application).getAppComponent().inject(this); addDisposable(getCommonViewModel().observeLocalFingerprint(accountId) .compose(schedulers.executeUiSafeObservable()) .filter(Optional::isPresent) .map(Optional::getItem) .subscribe(localFingerprint::postValue)); addDisposable(getCommonViewModel().observeIkeyFingerprint(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(ikeyFingerprint::postValue, e -> LOGGER.log(Level.SEVERE, "Error displaying ikey fingerprint", e))); addDisposable(getCommonViewModel().observeRemoteFingerprints(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(list -> { LOGGER.log(Level.INFO, "Set remote fingerprints to list: " + Arrays.toString(list.toArray())); remoteFingerprints.postValue(list); }, e -> LOGGER.log(Level.SEVERE, "Error observing remote fingerprints.", e), () -> LOGGER.log(Level.INFO, "observing remote fingerprint onComplete."))); addDisposable(getCommonViewModel().getJid(accountId).subscribe(jid::postValue)); addDisposable(getCommonViewModel().isAccountEnabled(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(bool -> accountEnabled.postValue(bool), e -> LOGGER.log(Level.SEVERE, "Error subscribing to account enabled state", e), () -> LOGGER.log(Level.INFO, "observing account enabled state onComplete."))); addDisposable(getCommonViewModel().isAccountAuthenticated(accountId) .compose(schedulers.executeUiSafeObservable()) .subscribe(bool -> accountAuthenticated.postValue(bool), e -> LOGGER.log(Level.SEVERE, "Error subscribing to account authenticated state", e), () -> LOGGER.log(Level.INFO, "observing account authenticated state onComplete."))); } @Override public AccountDetailsViewModel getCommonViewModel() { return commonViewModel; } public LiveData getJid() { return jid; } public void markFingerprintTrusted(OpenPgpV4Fingerprint fingerprint, boolean trusted) { getCommonViewModel().markFingerprintTrusted(accountId, fingerprint, trusted); } public void sendIkeyElement(UUID accountId) { getCommonViewModel().sendIkeyElement(accountId); } public LiveData> getIkeyFingerprint() { return ikeyFingerprint; } public LiveData getLocalFingerprint() { return localFingerprint; } public LiveData> getRemoteFingerprints() { return remoteFingerprints; } public void unpublishPublicKey(OpenPgpV4Fingerprint fingerprint) { addDisposable(getCommonViewModel().unpublishPublicKey(accountId, fingerprint) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "Successfully unpublished fingerprint " + fingerprint), e -> LOGGER.log(Level.SEVERE, "Error unpublishing fingerprint " + fingerprint, e))); } public void onGenerateIkey() { addDisposable(getCommonViewModel().generateIkey(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey generated for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not generate Ikey", e))); } public void onDeleteIkey() { addDisposable(getCommonViewModel().deleteIkey(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey deleted for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not delete Ikey", e))); } public void onRestoreIkeyBackup() { addDisposable(getCommonViewModel().restoreIkeyBackup(accountId) .subscribeOn(schedulers.getNewThread()) .observeOn(schedulers.getUiScheduler()) .subscribe(() -> LOGGER.log(Level.INFO, "IKey restored for account " + accountId), e -> LOGGER.log(Level.SEVERE, "Could not restore Ikey backup", e))); } public LiveData isAccountEnabled() { return accountEnabled; } public LiveData isAccountAuthenticated() { return accountAuthenticated; } public static class AndroidAccountDetailsViewModelFactory implements ViewModelProvider.Factory { private final Application application; private final UUID accountId; public AndroidAccountDetailsViewModelFactory(Application application, UUID accountId) { this.application = application; this.accountId = accountId; } @NonNull @Override public T create(@NonNull Class modelClass) { return (T) new AndroidAccountDetailsViewModel(application, accountId); } } }