Commit bec1f117 authored by Torsten Grote's avatar Torsten Grote

Remote Contact Adding: Rename methods and add more exception handling

parent 2c014b4e
package org.briarproject.bramble.api.contact;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
......@@ -60,16 +61,16 @@ public interface ContactManager {
/**
* Returns the static link that needs to be sent to the contact to be added.
*/
String getRemoteContactLink() throws DbException;
String getHandshakeLink() throws DbException;
/**
* Requests a new contact to be added via the given {@code link}.
*
* @param link The link received from the contact we want to add.
* @param alias The alias the user has given this contact.
* @return A PendingContact representing the contact to be added.
*/
void addRemoteContactRequest(String link, String alias);
void addPendingContact(String link, String alias)
throws DbException, FormatException;
/**
* Returns a list of {@link PendingContact}s.
......@@ -81,7 +82,7 @@ public interface ContactManager {
* {@link PendingContactState FAILED}.
* @param commitAction an action to run on the main thread after removing.
*/
void removePendingContact(PendingContact pendingContact,
void removePendingContact(PendingContactId pendingContact,
Runnable commitAction) throws DbException;
/**
......
......@@ -116,7 +116,7 @@ class ContactManagerImpl implements ContactManager {
}
@Override
public String getRemoteContactLink() {
public String getHandshakeLink() {
// TODO replace with real implementation
try {
Thread.sleep(1500);
......@@ -139,27 +139,23 @@ class ContactManagerImpl implements ContactManager {
}
@Override
public void addRemoteContactRequest(String link, String alias) {
public void addPendingContact(String link, String alias)
throws DbException {
// TODO replace with real implementation
try {
Thread.sleep(1500);
} catch (InterruptedException ignored) {
}
PendingContactId id = new PendingContactId(
link.substring(0, PendingContactId.LENGTH).getBytes());
PendingContact pendingContact =
new PendingContact(id, new byte[MAX_PUBLIC_KEY_LENGTH],
alias, WAITING_FOR_CONNECTION, currentTimeMillis());
dbExecutor.execute(() -> {
try {
Thread.sleep(1500);
} catch (InterruptedException ignored) {
}
try {
getLogger("TMP").warning("WAITING_FOR_CONNECTION");
pendingContacts.add(pendingContact);
Event e = new PendingContactStateChangedEvent(id,
WAITING_FOR_CONNECTION);
db.transaction(true, txn -> txn.attach(e));
} catch (DbException ignored) {
}
});
getLogger("TMP").warning("WAITING_FOR_CONNECTION");
pendingContacts.add(pendingContact);
Event event = new PendingContactStateChangedEvent(id,
WAITING_FOR_CONNECTION);
db.transaction(true, txn -> txn.attach(event));
scheduler.schedule(() -> dbExecutor.execute(() -> {
getLogger("TMP").warning("CONNECTED");
......@@ -222,10 +218,15 @@ class ContactManagerImpl implements ContactManager {
}
@Override
public void removePendingContact(PendingContact pendingContact,
public void removePendingContact(PendingContactId id,
Runnable commitAction) throws DbException {
// TODO replace with real implementation
pendingContacts.remove(pendingContact);
for (PendingContact pc : pendingContacts) {
if (pc.getId().equals(id)) {
pendingContacts.remove(pc);
break;
}
}
try {
Thread.sleep(250);
} catch (InterruptedException ignored) {
......
......@@ -63,7 +63,7 @@ public class AddContactActivity extends BriarActivity implements
String text = i.getStringExtra(EXTRA_TEXT);
if (text != null) {
if (viewModel.isValidRemoteContactLink(text)) {
viewModel.setRemoteContactLink(text);
viewModel.setRemoteHandshakeLink(text);
} else {
Toast.makeText(this, R.string.invalid_link, LENGTH_LONG)
.show();
......@@ -72,7 +72,7 @@ public class AddContactActivity extends BriarActivity implements
String uri = i.getDataString();
if (uri != null) {
if (viewModel.isValidRemoteContactLink(uri)) {
viewModel.setRemoteContactLink(uri);
viewModel.setRemoteHandshakeLink(uri);
} else {
Toast.makeText(this, R.string.invalid_link, LENGTH_LONG)
.show();
......
......@@ -7,6 +7,7 @@ import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.briarproject.bramble.api.FormatException;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.db.DatabaseExecutor;
import org.briarproject.bramble.api.db.DbException;
......@@ -32,11 +33,14 @@ public class AddContactViewModel extends AndroidViewModel {
@DatabaseExecutor
private final Executor dbExecutor;
private final MutableLiveData<String> ourLink = new MutableLiveData<>();
private final MutableLiveData<String> handshakeLink =
new MutableLiveData<>();
private final MutableLiveData<Boolean> remoteLinkEntered =
new MutableLiveData<>();
private final MutableLiveData<Boolean> addContactResult =
new MutableLiveData<>();
@Nullable
private String remoteContactLink;
private String remoteHandshakeLink;
@Inject
public AddContactViewModel(@NonNull Application application,
......@@ -45,13 +49,13 @@ public class AddContactViewModel extends AndroidViewModel {
super(application);
this.contactManager = contactManager;
this.dbExecutor = dbExecutor;
loadOurLink();
loadHandshakeLink();
}
private void loadOurLink() {
private void loadHandshakeLink() {
dbExecutor.execute(() -> {
try {
ourLink.postValue(contactManager.getRemoteContactLink());
handshakeLink.postValue(contactManager.getHandshakeLink());
} catch (DbException e) {
logException(LOG, WARNING, e);
// the UI should stay disable in this case,
......@@ -60,12 +64,12 @@ public class AddContactViewModel extends AndroidViewModel {
});
}
LiveData<String> getOurLink() {
return ourLink;
LiveData<String> getHandshakeLink() {
return handshakeLink;
}
void setRemoteContactLink(String link) {
remoteContactLink = link;
void setRemoteHandshakeLink(String link) {
remoteHandshakeLink = link;
}
boolean isValidRemoteContactLink(@Nullable CharSequence link) {
......@@ -77,14 +81,26 @@ public class AddContactViewModel extends AndroidViewModel {
}
void onRemoteLinkEntered() {
if (remoteContactLink == null) throw new IllegalStateException();
if (remoteHandshakeLink == null) throw new IllegalStateException();
remoteLinkEntered.setValue(true);
remoteLinkEntered.postValue(false); // reset, so we can navigate back
}
void addContact(String nickname) {
if (remoteContactLink == null) throw new IllegalStateException();
contactManager.addRemoteContactRequest(remoteContactLink, nickname);
if (remoteHandshakeLink == null) throw new IllegalStateException();
dbExecutor.execute(() -> {
try {
contactManager.addPendingContact(remoteHandshakeLink, nickname);
addContactResult.postValue(true);
} catch (DbException | FormatException e) {
logException(LOG, WARNING, e);
addContactResult.postValue(false);
}
});
}
public LiveData<Boolean> getAddContactResult() {
return addContactResult;
}
}
......@@ -83,12 +83,13 @@ public class LinkExchangeFragment extends BaseFragment {
linkInput.setText(clipData.getItemAt(0).getText());
});
observeOnce(viewModel.getOurLink(), this, this::onOwnLinkLoaded);
observeOnce(viewModel.getHandshakeLink(), this,
this::onHandshakeLinkLoaded);
return v;
}
private void onOwnLinkLoaded(String link) {
private void onHandshakeLinkLoaded(String link) {
View v = requireNonNull(getView());
TextView linkView = v.findViewById(R.id.linkView);
......@@ -118,10 +119,10 @@ public class LinkExchangeFragment extends BaseFragment {
}
/**
* Requires {@link AddContactViewModel#getOurLink()} to be loaded.
* Requires {@link AddContactViewModel#getHandshakeLink()} to be loaded.
*/
@Nullable
private String getEnteredLinkOrNull() {
private String getRemoteHandshakeLinkOrNull() {
CharSequence link = linkInput.getText();
if (link == null || link.length() == 0) {
linkInputLayout.setError(getString(R.string.missing_link));
......@@ -135,7 +136,7 @@ public class LinkExchangeFragment extends BaseFragment {
// Check also if this is our own link. This was loaded already,
// because it enables the Continue button which is the only caller.
if (("briar://" + linkWithoutSchema)
.equals(viewModel.getOurLink().getValue())) {
.equals(viewModel.getHandshakeLink().getValue())) {
linkInputLayout.setError(getString(R.string.own_link_error));
linkInput.requestFocus();
return null;
......@@ -149,10 +150,10 @@ public class LinkExchangeFragment extends BaseFragment {
}
private void onContinueButtonClicked() {
String link = getEnteredLinkOrNull();
String link = getRemoteHandshakeLinkOrNull();
if (link == null) return; // invalid link
viewModel.setRemoteContactLink(link);
viewModel.setRemoteHandshakeLink(link);
viewModel.onRemoteLinkEntered();
}
......
......@@ -11,6 +11,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
......@@ -21,6 +23,9 @@ import org.briarproject.briar.android.fragment.BaseFragment;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.view.View.INVISIBLE;
import static android.view.View.VISIBLE;
import static android.widget.Toast.LENGTH_LONG;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.utf8IsTooLong;
......@@ -37,6 +42,8 @@ public class NicknameFragment extends BaseFragment {
private TextInputLayout contactNameLayout;
private TextInputEditText contactNameInput;
private Button addButton;
private ProgressBar progressBar;
@Override
public String getUniqueTag() {
......@@ -61,12 +68,14 @@ public class NicknameFragment extends BaseFragment {
viewModel = ViewModelProviders.of(getActivity(), viewModelFactory)
.get(AddContactViewModel.class);
Button addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked());
contactNameLayout = v.findViewById(R.id.contactNameLayout);
contactNameInput = v.findViewById(R.id.contactNameInput);
addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked());
progressBar = v.findViewById(R.id.progressBar);
return v;
}
......@@ -91,12 +100,22 @@ public class NicknameFragment extends BaseFragment {
String name = getNicknameOrNull();
if (name == null) return; // invalid nickname
addButton.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
viewModel.getAddContactResult().observe(this, success -> {
if (success == null) return;
if (success) {
Intent intent = new Intent(getActivity(),
PendingContactListActivity.class);
startActivity(intent);
} else {
Toast.makeText(getContext(), R.string.adding_contact_error,
LENGTH_LONG).show();
}
finish();
});
viewModel.addContact(name);
Intent intent =
new Intent(getActivity(), PendingContactListActivity.class);
startActivity(intent);
finish();
}
}
......@@ -86,7 +86,7 @@ public class PendingContactListActivity extends BriarActivity
@Override
public void onFailedPendingContactRemoved(PendingContact pendingContact) {
viewModel.removePendingContact(pendingContact,
viewModel.removePendingContact(pendingContact.getId(),
() -> adapter.remove(pendingContact));
}
......
......@@ -7,6 +7,7 @@ import android.arch.lifecycle.MutableLiveData;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.PendingContact;
import org.briarproject.bramble.api.contact.PendingContactId;
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
import org.briarproject.bramble.api.db.DatabaseExecutor;
......@@ -81,12 +82,11 @@ public class PendingContactListViewModel extends AndroidViewModel
return pendingContacts;
}
void removePendingContact(PendingContact pendingContact,
Runnable commitAction) {
void removePendingContact(PendingContactId id, Runnable commitAction) {
dbExecutor.execute(() -> {
try {
contactManager
.removePendingContact(pendingContact, commitAction);
.removePendingContact(id, commitAction);
} catch (DbException e) {
logException(LOG, WARNING, e);
}
......
......@@ -145,6 +145,19 @@
app:layout_constraintTop_toBottomOf="@+id/contactNameLayout"
app:layout_constraintVertical_bias="1.0"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contactNameLayout"
app:layout_constraintVertical_bias="1.0"/>
</android.support.constraint.ConstraintLayout>
</ScrollView>
\ No newline at end of file
......@@ -188,6 +188,7 @@
<string name="your_link">Give this link to the contact you want to add</string>
<string name="link_clip_label">Briar link</string>
<string name="link_copied_toast">Link copied</string>
<string name="adding_contact_error">There was an error adding the contact.</string>
<string name="pending_contact_requests_snackbar">There are pending contact requests</string>
<string name="pending_contact_requests">Pending Contact Requests</string>
<string name="no_pending_contacts">No pending contacts</string>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment