diff --git a/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/AndroidIkeyBackupCreationViewModel.java b/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/AndroidIkeyBackupCreationViewModel.java index beb7586..1af6853 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/AndroidIkeyBackupCreationViewModel.java +++ b/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/AndroidIkeyBackupCreationViewModel.java @@ -6,7 +6,11 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import org.bouncycastle.openpgp.PGPException; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; +import org.jivesoftware.smackx.pubsub.PubSubException; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.ui.MercuryAndroidViewModel; import org.mercury_im.messenger.android.util.QrCodeGenerator; @@ -15,6 +19,7 @@ import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGene import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.ikey.IkeySecretKeyBackupCreationViewModel; +import java.io.IOException; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; @@ -81,4 +86,11 @@ public class AndroidIkeyBackupCreationViewModel extends ViewModel implements Mer public IkeySecretKeyBackupCreationViewModel getCommonViewModel() { return commonViewModel; } + + public void uploadBackup() { + addDisposable(getCommonViewModel().createBackup() + .compose(schedulers.executeUiSafeCompletable()) + .subscribe(() -> LOGGER.log(Level.INFO, "Successfully uploaded ikey backup."), + e -> LOGGER.log(Level.INFO, "Error uploading ikey backup:", e))); + } } diff --git a/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/IkeyBackupCreationFragment.java b/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/IkeyBackupCreationFragment.java index 058cd3f..538de9a 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/IkeyBackupCreationFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/crypto/ikey/IkeyBackupCreationFragment.java @@ -14,8 +14,13 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import org.bouncycastle.openpgp.PGPException; +import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smackx.pubsub.PubSubException; import org.mercury_im.messenger.R; +import java.io.IOException; import java.util.UUID; import butterknife.BindView; @@ -55,6 +60,8 @@ public class IkeyBackupCreationFragment extends Fragment { viewModel = new ViewModelProvider(this).get(AndroidIkeyBackupCreationViewModel.class); viewModel.initialize(accountId); + viewModel.uploadBackup(); + viewModel.getPassphrase().observe(getViewLifecycleOwner(), passphrase -> backupCode.setText(passphrase)); viewModel.getPassphraseAsQrCode().observe(getViewLifecycleOwner(), bitmap -> qrCode.setImageBitmap(bitmap)); } diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java index e78d2f3..28947a3 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java @@ -4,9 +4,9 @@ import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule; import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule; import org.mercury_im.messenger.android.ui.account.detail.AndroidAccountDetailsViewModel; -import org.mercury_im.messenger.android.ui.account.login.AddAccountActivity; +import org.mercury_im.messenger.android.ui.account.login.AndroidIkeyInfoViewModel; import org.mercury_im.messenger.android.ui.account.login.EnterAccountDetailsFragment; -import org.mercury_im.messenger.android.ui.account.login.IkeySetupViewModel; +import org.mercury_im.messenger.android.ui.account.login.AndroidIkeySetupViewModel; import org.mercury_im.messenger.android.ui.contacts.AndroidContactListViewModel; import org.mercury_im.messenger.android.crypto.ikey.AndroidIkeyBackupCreationViewModel; import org.mercury_im.messenger.core.di.module.IkeyModule; @@ -101,9 +101,11 @@ public interface AppComponent { void inject(AndroidIkeyBackupCreationViewModel androidIkeyBackupCreationViewModel); - void inject(IkeySetupViewModel ikeySetupViewModel); + void inject(AndroidIkeySetupViewModel androidIkeySetupViewModel); // void inject(AndroidOxSecretKeyBackupRestoreViewModel androidOxSecretKeyBackupRestoreViewModel); + void inject(AndroidIkeyInfoViewModel androidIkeyInfoViewModel); + // Common VMs void inject(LoginViewModel loginViewModel); diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsActivity.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsActivity.java index a25992d..b45ad94 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/detail/AccountDetailsActivity.java @@ -1,6 +1,7 @@ package org.mercury_im.messenger.android.ui.account.detail; import android.os.Bundle; +import android.view.Menu; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AddAccountActivity.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AddAccountActivity.java index 6e2e8e3..597689c 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AddAccountActivity.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AddAccountActivity.java @@ -34,7 +34,7 @@ public class AddAccountActivity extends AppCompatActivity { private SetupPagerAdapter pagerAdapter; private AppComponent appComponent; - private IkeySetupViewModel ikeyViewModel; + private AndroidIkeySetupViewModel ikeyViewModel; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { @@ -47,7 +47,7 @@ public class AddAccountActivity extends AppCompatActivity { viewPager.setAdapter(pagerAdapter); viewPager.setUserInputEnabled(false); // disable swiping - ikeyViewModel = new ViewModelProvider(this).get(IkeySetupViewModel.class); // shared between fragments + ikeyViewModel = new ViewModelProvider(this).get(AndroidIkeySetupViewModel.class); // shared between fragments } public void loginFinished(Optional optionalAccount) { @@ -58,29 +58,32 @@ public class AddAccountActivity extends AppCompatActivity { } } - public void skipIkeySetup() { - finish(); - } - public void setupIkey(UUID accountId) { - int pos = pagerAdapter.getItemCount(); - pagerAdapter.getFragments().put(pos, IkeyBackupRestoreOrSkipFragment.newInstance(accountId)); + int nextPos = pagerAdapter.getItemCount(); + pagerAdapter.getFragments().put(nextPos, IkeyBackupRestoreOrSkipFragment.newInstance(accountId)); pagerAdapter.notifyDataSetChanged(); - viewPager.setCurrentItem(pos); + viewPager.setCurrentItem(nextPos); } - public void restoreIkeyBackup(UUID accountId) { - int pos = pagerAdapter.getItemCount(); - pagerAdapter.getFragments().put(pos, IkeyBackupRestoreSuccessfulFragment.newInstance(accountId)); + public void restoreSuccessful(UUID accountId) { + int nextPos = pagerAdapter.getItemCount(); + pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId)); pagerAdapter.notifyDataSetChanged(); - viewPager.setCurrentItem(pos); + viewPager.setCurrentItem(nextPos); } public void generateIkeyBackup(UUID accountId) { - int pos = pagerAdapter.getItemCount(); - pagerAdapter.getFragments().put(pos, IkeyBackupCreationFragment.newInstance(accountId)); + int nextPos = pagerAdapter.getItemCount(); + pagerAdapter.getFragments().put(nextPos, IkeyBackupCreationFragment.newInstance(accountId)); pagerAdapter.notifyDataSetChanged(); - viewPager.setCurrentItem(pos); + viewPager.setCurrentItem(nextPos); + } + + public void displayInfo(UUID accountId) { + int nextPos = pagerAdapter.getItemCount(); + pagerAdapter.getFragments().put(nextPos, IkeyKeyInfoFragment.newInstance(accountId)); + pagerAdapter.notifyDataSetChanged(); + viewPager.setCurrentItem(nextPos); } private class SetupPagerAdapter extends FragmentStateAdapter { diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeyInfoViewModel.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeyInfoViewModel.java new file mode 100644 index 0000000..be2b32d --- /dev/null +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeyInfoViewModel.java @@ -0,0 +1,51 @@ +package org.mercury_im.messenger.android.ui.account.login; + +import android.app.Application; +import android.text.Spannable; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import org.mercury_im.messenger.android.MercuryImApplication; +import org.mercury_im.messenger.android.ui.MercuryAndroidViewModel; +import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter; +import org.mercury_im.messenger.core.util.Optional; +import org.mercury_im.messenger.core.viewmodel.ikey.IkeyInfoViewModel; + +import java.util.UUID; + +import javax.inject.Inject; + +public class AndroidIkeyInfoViewModel extends AndroidViewModel implements MercuryAndroidViewModel { + + private MutableLiveData fingerprint = new MutableLiveData<>(); + + @Inject + IkeyInfoViewModel commonViewModel; + + public AndroidIkeyInfoViewModel(@NonNull Application application) { + super(application); + ((MercuryImApplication) application).getAppComponent().inject(this); + } + + public void init(UUID accountId) { + getCommonViewModel().init(accountId); + + addDisposable(getCommonViewModel().getFingerprint() + .filter(Optional::isPresent) + .map(Optional::getItem) + .map(OpenPgpV4FingerprintFormatter::formatOpenPgpV4Fingerprint) + .subscribe(fingerprint::postValue)); + } + + public LiveData getFingerprint() { + return fingerprint; + } + + @Override + public IkeyInfoViewModel getCommonViewModel() { + return commonViewModel; + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeySetupViewModel.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeySetupViewModel.java new file mode 100644 index 0000000..7b15c1c --- /dev/null +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/AndroidIkeySetupViewModel.java @@ -0,0 +1,85 @@ +package org.mercury_im.messenger.android.ui.account.login; + +import android.app.Application; +import android.graphics.Path; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; + +import org.bouncycastle.openpgp.PGPException; +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; +import org.jivesoftware.smackx.ox.element.SecretkeyElement; +import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException; +import org.mercury_im.messenger.R; +import org.mercury_im.messenger.android.MercuryImApplication; +import org.mercury_im.messenger.android.ui.MercuryAndroidViewModel; +import org.mercury_im.messenger.core.util.Optional; +import org.mercury_im.messenger.core.viewmodel.ikey.IkeySetupViewModel; + +import java.io.IOException; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.UUID; + +import javax.inject.Inject; + +import io.reactivex.Single; + +public class AndroidIkeySetupViewModel extends AndroidViewModel implements MercuryAndroidViewModel { + + @Inject + IkeySetupViewModel commonViewModel; + + private MutableLiveData> passphraseError = new MutableLiveData<>(); + + public AndroidIkeySetupViewModel(@NonNull Application application) { + super(application); + MercuryImApplication.getApplication().getAppComponent().inject(this); + } + + public void init(UUID accountId) { + getCommonViewModel().init(accountId); + } + + public Single> fetchBackupElement() { + return getCommonViewModel().fetchBackupElement(); + } + + @Override + public IkeySetupViewModel getCommonViewModel() { + return commonViewModel; + } + + public void generateIdentityKey() throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException { + getCommonViewModel().generateIdentityKey(); + } + + public boolean restoreBackup(String backupCode) { + OpenPgpSecretKeyBackupPassphrase passphrase; + try { + passphrase = new OpenPgpSecretKeyBackupPassphrase(backupCode); + } catch (IllegalArgumentException e) { + passphraseError.setValue(new Optional<>("Malformed Passphrase")); + return false; + } + + try { + getCommonViewModel().restoreBackup(passphrase); + passphraseError.setValue(new Optional<>()); + return true; + } catch (InvalidBackupCodeException e) { + passphraseError.setValue(new Optional<>("Wrong Passphrase")); + } catch (IOException | PGPException e) { + passphraseError.setValue(new Optional<>("Error: " + e.getMessage())); + } + return false; + } + + public LiveData> getPassphraseError() { + return passphraseError; + } +} diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreOrSkipFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreOrSkipFragment.java index 3e17d0d..aa3586e 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreOrSkipFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreOrSkipFragment.java @@ -1,6 +1,5 @@ package org.mercury_im.messenger.android.ui.account.login; -import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -8,6 +7,7 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -37,7 +37,7 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment { private final UUID accountId; - private IkeySetupViewModel viewModel; + private AndroidIkeySetupViewModel viewModel; IkeyBackupRestoreOrSkipFragment(UUID accountId) { this.accountId = accountId; @@ -58,11 +58,25 @@ public class IkeyBackupRestoreOrSkipFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - viewModel = new ViewModelProvider(requireActivity()).get(IkeySetupViewModel.class); + viewModel = new ViewModelProvider(requireActivity()).get(AndroidIkeySetupViewModel.class); - restoreButton.setOnClickListener(v -> - ((AddAccountActivity) getActivity()).restoreIkeyBackup(accountId)); + restoreButton.setOnClickListener(v -> onRestore()); regenerateButton.setOnClickListener(v -> ((AddAccountActivity) getActivity()).generateIkeyBackup(accountId)); + + viewModel.getPassphraseError().observe(this, opt -> { + if (opt.isPresent()) { + Toast.makeText(getContext(), opt.getItem(), Toast.LENGTH_SHORT).show(); + } + }); + } + + public void onRestore() { + String backupCode = backupCodeEditText.getText().toString(); + + if (viewModel.restoreBackup(backupCode)) { + ((AddAccountActivity) getActivity()).restoreSuccessful(accountId); + } + } } diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreSuccessfulFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyKeyInfoFragment.java similarity index 54% rename from app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreSuccessfulFragment.java rename to app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyKeyInfoFragment.java index 2cca734..759e7f7 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyBackupRestoreSuccessfulFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeyKeyInfoFragment.java @@ -1,5 +1,6 @@ package org.mercury_im.messenger.android.ui.account.login; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -19,29 +20,33 @@ import java.util.UUID; import butterknife.BindView; import butterknife.ButterKnife; -public class IkeyBackupRestoreSuccessfulFragment extends Fragment { +public class IkeyKeyInfoFragment extends Fragment { - @BindView(R.id.btn_done) - Button doneButton; - - @BindView(R.id.text) + @BindView(R.id.fingerprint) TextView fingerprint; - private final UUID accountId; - private IkeySetupViewModel viewModel; + @BindView(R.id.btn_backup_ikey) + Button buttonBackupIkey; - IkeyBackupRestoreSuccessfulFragment(UUID accountId) { + @BindView(R.id.btn_done) + Button buttonDone; + + private final UUID accountId; + + private AndroidIkeyInfoViewModel viewModel; + + public IkeyKeyInfoFragment(UUID accountId) { this.accountId = accountId; } - public static IkeyBackupRestoreSuccessfulFragment newInstance(UUID accountId) { - return new IkeyBackupRestoreSuccessfulFragment(accountId); + public static Fragment newInstance(UUID accountId) { + return new IkeyKeyInfoFragment(accountId); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View view = inflater.inflate(R.layout.fragment_ikey_backup_restore_success, container); + View view = inflater.inflate(R.layout.fragment_ikey_key_info, container, false); ButterKnife.bind(this, view); return view; } @@ -49,8 +54,12 @@ public class IkeyBackupRestoreSuccessfulFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - viewModel = new ViewModelProvider(requireActivity()).get(IkeySetupViewModel.class); - doneButton.setOnClickListener(v -> getActivity().finish()); + this.viewModel = new ViewModelProvider(this).get(AndroidIkeyInfoViewModel.class); + viewModel.init(accountId); + viewModel.getFingerprint().observe(this, f -> fingerprint.setText(f)); + + buttonBackupIkey.setOnClickListener(v -> ((AddAccountActivity)getActivity()).generateIkeyBackup(accountId)); + buttonDone.setOnClickListener(v -> getActivity().finish()); } } diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupFragment.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupFragment.java index 76b5bcc..29bd632 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupFragment.java +++ b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupFragment.java @@ -1,6 +1,5 @@ package org.mercury_im.messenger.android.ui.account.login; -import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -30,7 +29,7 @@ public class IkeySetupFragment extends Fragment { Button continueButton; private final UUID accountId; - private IkeySetupViewModel viewModel; + private AndroidIkeySetupViewModel viewModel; public IkeySetupFragment(UUID accountId) { this.accountId = accountId; @@ -51,7 +50,7 @@ public class IkeySetupFragment extends Fragment { @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - viewModel = new ViewModelProvider(requireActivity()).get(IkeySetupViewModel.class); + viewModel = new ViewModelProvider(requireActivity()).get(AndroidIkeySetupViewModel.class); viewModel.init(accountId); skipButton.setOnClickListener(v -> @@ -65,7 +64,8 @@ public class IkeySetupFragment extends Fragment { if (opt.isPresent()) { ((AddAccountActivity) getActivity()).setupIkey(accountId); } else { - ((AddAccountActivity) getActivity()).generateIkeyBackup(accountId); + viewModel.generateIdentityKey(); + ((AddAccountActivity) getActivity()).displayInfo(accountId); } }) .subscribe(); diff --git a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupViewModel.java b/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupViewModel.java deleted file mode 100644 index 1c1f51b..0000000 --- a/app/src/main/java/org/mercury_im/messenger/android/ui/account/login/IkeySetupViewModel.java +++ /dev/null @@ -1,73 +0,0 @@ -package org.mercury_im.messenger.android.ui.account.login; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; - -import org.jivesoftware.smack.SmackException; -import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smackx.ikey.IkeyManager; -import org.jivesoftware.smackx.ox.element.SecretkeyElement; -import org.jivesoftware.smackx.pubsub.PubSubException; -import org.mercury_im.messenger.android.MercuryImApplication; -import org.mercury_im.messenger.core.connection.MercuryConnection; -import org.mercury_im.messenger.core.connection.MercuryConnectionManager; -import org.mercury_im.messenger.core.crypto.ikey.IkeyInitializer; -import org.mercury_im.messenger.core.util.Optional; - -import java.util.UUID; - -import javax.inject.Inject; - -import io.reactivex.Maybe; -import io.reactivex.MaybeObserver; -import io.reactivex.Single; - -public class IkeySetupViewModel extends AndroidViewModel { - - @Inject - MercuryConnectionManager connectionManager; - - @Inject - IkeyInitializer ikeyInitializer; - - IkeyManager ikeyManager; - private SecretkeyElement secretkeyElement; - - public IkeySetupViewModel(@NonNull Application application) { - super(application); - MercuryImApplication.getApplication().getAppComponent().inject(this); - } - - public void init(UUID accountId) { - MercuryConnection connection = connectionManager.getConnection(accountId); - ikeyManager = ikeyInitializer.initFor(connection); - } - - public Single> fetchBackupElement() { - return fetchMaybeBackupElement() - .map(Optional::new) - .toSingle(new Optional<>()); - } - - private Maybe fetchMaybeBackupElement() { - return new Maybe() { - @Override - protected void subscribeActual(MaybeObserver observer) { - try { - secretkeyElement = ikeyManager.fetchSecretIdentityKey(); - if (secretkeyElement != null) { - observer.onSuccess(secretkeyElement); - } else { - observer.onComplete(); - } - } catch (PubSubException.NotALeafNodeException e) { - observer.onComplete(); - } catch (InterruptedException | XMPPException.XMPPErrorException | SmackException.NotConnectedException | SmackException.NoResponseException e) { - observer.onError(e); - } - } - }; - } -} diff --git a/app/src/main/res/layout/fragment_ikey_key_info.xml b/app/src/main/res/layout/fragment_ikey_key_info.xml new file mode 100644 index 0000000..78fa8ac --- /dev/null +++ b/app/src/main/res/layout/fragment_ikey_key_info.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + +