Improvements for second testing round

This commit is contained in:
Torsten Grote
2018-11-21 16:24:26 -02:00
parent 6985f2d31a
commit ecc73b95e3
14 changed files with 170 additions and 85 deletions

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 24 24"
xml:space="preserve"
id="svg22"
sodipodi:docname="ic_nearby.svg"
width="24"
height="24"
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
id="metadata28"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs26" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview24"
showgrid="false"
inkscape:zoom="11.125147"
inkscape:cx="-4.1072694"
inkscape:cy="21.111303"
inkscape:window-x="1440"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg22" /><path
d="M 12,0 C 5.373,0 0,5.373 0,12 c 0,6.627 5.373,12 12,12 2.235,0 4.320281,-0.6235 6.113281,-1.6875 -0.266,-0.217 -0.492875,-0.472625 -0.671875,-0.765625 C 15.835406,22.466875 13.98,23 12,23 5.935,23 1,18.065 1,12 1,5.935 5.935,1 12,1 c 6.064,0 11,4.935 11,11 0,1.981 -0.533125,3.834406 -1.453125,5.441406 0.293,0.178 0.548625,0.405922 0.765625,0.669922 C 23.3765,16.320328 24,14.235 24,12 24,5.373 18.627,0 12,0 Z m 3,4 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m -3,1 c -3.866,0 -7,3.134 -7,7 0,0.061 0.00777,0.120641 0.00977,0.181641 C 5.3197656,12.070641 5.65,12 6,12 6,8.691 8.691,6 12,6 12,5.651 12.070641,5.3217656 12.181641,5.0097656 12.120641,5.0087656 12.061,5 12,5 Z m 5.492188,2.6679688 c -0.190001,0.283 -0.435032,0.5245156 -0.707032,0.7285156 C 17.544156,9.4014844 18,10.648 18,12 c 0,3.309 -2.691,6 -6,6 -1.354,0 -2.5985156,-0.456844 -3.6035156,-1.214844 -0.204,0.272 -0.4455157,0.517032 -0.7285156,0.707032 C 8.8589687,18.434187 10.362,19 12,19 c 3.866,0 7,-3.134 7,-7 0,-1.638 -0.565812,-3.1400312 -1.507812,-4.3320312 z M 12,10 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m -6,3 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z m 14,5 a 2,2 0 0 0 -2,2 2,2 0 0 0 2,2 2,2 0 0 0 2,-2 2,2 0 0 0 -2,-2 z"
id="path2"
inkscape:connector-curvature="0" /></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -7,8 +7,11 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.view.MenuItem; import android.view.MenuItem;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.plugin.ConnectionRegistry;
import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.system.Clock; import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
@@ -30,7 +33,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.SystemClock.elapsedRealtime; import static android.os.SystemClock.elapsedRealtime;
import static java.lang.String.CASE_INSENSITIVE_ORDER; import static java.lang.String.CASE_INSENSITIVE_ORDER;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
@@ -52,6 +55,8 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
@Inject @Inject
MessagingManager messagingManager; MessagingManager messagingManager;
@Inject @Inject
ConnectionRegistry connectionRegistry;
@Inject
Clock clock; Clock clock;
@Override @Override
@@ -87,7 +92,7 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
} }
} else if ("addContact".equals(action)) { } else if ("addContact".equals(action)) {
removeFakeRequest(i.getStringExtra("name"), removeFakeRequest(i.getStringExtra("name"),
i.getLongExtra("timestamp", 0)); i.getLongExtra("timestamp", 0), i.getLongExtra("addAt", 0));
setIntent(null); setIntent(null);
finish(); finish();
} }
@@ -126,26 +131,30 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
} }
void addFakeRequest(String name, String link) { void addFakeRequest(String name, String link) {
long timestamp = clock.currentTimeMillis();
try {
messagingManager.addNewPendingContact(name, timestamp);
} catch (DbException e) {
logException(LOG, WARNING, e);
}
AlarmManager alarmManager = AlarmManager alarmManager =
(AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE)); (AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE));
double random = getPseudoRandom(link, OUR_LINK.replace("briar://", "")); double random = getPseudoRandom(link, OUR_LINK.replace("briar://", ""));
long m = MINUTES.toMillis(1); long m = SECONDS.toMillis(50);
long fromNow = (long) (-m * Math.log(random)); long fromNow = (long) (-m * Math.log(random));
// it should take at least 30 seconds
if (fromNow < SECONDS.toMillis(30)) fromNow = SECONDS.toMillis(30);
LOG.info("Delay " + fromNow + " ms based on seed " + random); LOG.info("Delay " + fromNow + " ms based on seed " + random);
long triggerAt = elapsedRealtime() + fromNow; long triggerAt = elapsedRealtime() + fromNow;
long timestamp = clock.currentTimeMillis();
try {
messagingManager.addNewPendingContact(name, timestamp, timestamp + fromNow);
} catch (DbException e) {
logException(LOG, WARNING, e);
}
Intent i = new Intent(this, ContactLinkExchangeActivity.class); Intent i = new Intent(this, ContactLinkExchangeActivity.class);
i.setAction("addContact"); i.setAction("addContact");
i.setFlags(FLAG_ACTIVITY_NEW_TASK); i.setFlags(FLAG_ACTIVITY_NEW_TASK);
i.putExtra("name", name); i.putExtra("name", name);
i.putExtra("timestamp", timestamp); i.putExtra("timestamp", timestamp);
i.putExtra("addAt", timestamp + fromNow);
PendingIntent pendingIntent = PendingIntent pendingIntent =
PendingIntent.getActivity(this, (int) timestamp / 1000, i, 0); PendingIntent.getActivity(this, (int) timestamp / 1000, i, 0);
alarmManager.set(ELAPSED_REALTIME, triggerAt, pendingIntent); alarmManager.set(ELAPSED_REALTIME, triggerAt, pendingIntent);
@@ -169,14 +178,17 @@ public class ContactLinkExchangeActivity extends BriarActivity implements
return hash / (1.0 + Integer.MAX_VALUE); return hash / (1.0 + Integer.MAX_VALUE);
} }
private void removeFakeRequest(String name, long timestamp) { private void removeFakeRequest(String name, long timestamp, long addAt) {
if (lifecycleManager.getLifecycleState() != RUNNING) { if (lifecycleManager.getLifecycleState() != RUNNING) {
LOG.info("Lifecycle not started, not adding contact " + name); LOG.info("Lifecycle not started, not adding contact " + name);
return; return;
} }
LOG.info("Adding Contact " + name); LOG.info("Adding Contact " + name);
try { try {
messagingManager.removePendingContact(name, timestamp); ContactId c = messagingManager
.removePendingContact(name, timestamp, addAt);
// fake contact online status
connectionRegistry.registerConnection(c, TorConstants.ID, true);
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
} }

View File

@@ -8,9 +8,6 @@ import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.TextInputEditText; import android.support.design.widget.TextInputEditText;
import android.support.design.widget.TextInputLayout; import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -37,9 +34,9 @@ import static java.util.Objects.requireNonNull;
import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.LINK_REGEX; import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.LINK_REGEX;
import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK; import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK;
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute; import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
import static org.briarproject.briar.android.util.UiUtils.setError;
public class ContactLinkExchangeFragment extends BaseFragment public class ContactLinkExchangeFragment extends BaseFragment {
implements TextWatcher {
static final String TAG = ContactLinkExchangeFragment.class.getName(); static final String TAG = ContactLinkExchangeFragment.class.getName();
@@ -52,7 +49,7 @@ public class ContactLinkExchangeFragment extends BaseFragment
} }
private ClipboardManager clipboard; private ClipboardManager clipboard;
private TextInputLayout linkInputLayout; private TextInputLayout linkInputLayout, contactNameLayout;
private TextInputEditText linkInput, contactNameInput; private TextInputEditText linkInput, contactNameInput;
private Button addButton; private Button addButton;
@@ -87,8 +84,8 @@ public class ContactLinkExchangeFragment extends BaseFragment
addButton = v.findViewById(R.id.addButton); addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked()); addButton.setOnClickListener(view -> onAddButtonClicked());
contactNameLayout = v.findViewById(R.id.contactNameLayout);
contactNameInput = v.findViewById(R.id.contactNameInput); contactNameInput = v.findViewById(R.id.contactNameInput);
contactNameInput.addTextChangedListener(this);
if (SDK_INT < 23) { if (SDK_INT < 23) {
Drawable drawable = Drawable drawable =
wrap(contactNameInput.getCompoundDrawables()[0]); wrap(contactNameInput.getCompoundDrawables()[0]);
@@ -103,7 +100,6 @@ public class ContactLinkExchangeFragment extends BaseFragment
setTint(drawable, color); setTint(drawable, color);
linkInput.setCompoundDrawables(drawable, null, null, null); linkInput.setCompoundDrawables(drawable, null, null, null);
} }
linkInput.addTextChangedListener(this);
if (getArguments() != null) if (getArguments() != null)
linkInput.setText(getArguments().getString("link")); linkInput.setText(getArguments().getString("link"));
@@ -155,31 +151,26 @@ public class ContactLinkExchangeFragment extends BaseFragment
return (ContactLinkExchangeActivity) getActivity(); return (ContactLinkExchangeActivity) getActivity();
} }
@Override private boolean isInputError() {
public void beforeTextChanged(CharSequence s, int start, int count, boolean briarLink = isBriarLink(linkInput.getText());
int after) { if (!briarLink) {
} linkInputLayout.setError("Invalid link");
return true;
@Override } else linkInputLayout.setError(null);
public void onTextChanged(CharSequence s, int start, int before, String link = getLink();
int count) { boolean isOurLink = link != null && OUR_LINK.equals("briar://" + link);
updateAddButtonState(); if (isOurLink) {
} linkInputLayout.setError("Add your peer's link, not your own.");
return true;
@Override } else linkInputLayout.setError(null);
public void afterTextChanged(Editable s) {
}
private void updateAddButtonState() {
boolean validContactName = contactNameInput.getText() != null && boolean validContactName = contactNameInput.getText() != null &&
contactNameInput.getText().length() > 0; contactNameInput.getText().length() > 0;
boolean briarLink = isBriarLink(linkInput.getText()); if (!validContactName) {
if (briarLink) { contactNameLayout.setError("Nickname is missing");
linkInputLayout.setErrorEnabled(false); return true;
} else { } else contactNameLayout.setError(null);
linkInputLayout.setError("Invalid link"); setError(linkInputLayout, null, false);
} return false;
addButton.setEnabled(validContactName && briarLink);
} }
private boolean isBriarLink(@Nullable CharSequence s) { private boolean isBriarLink(@Nullable CharSequence s) {
@@ -198,23 +189,10 @@ public class ContactLinkExchangeFragment extends BaseFragment
private void onAddButtonClicked() { private void onAddButtonClicked() {
ContactLinkExchangeActivity activity = getCastActivity(); ContactLinkExchangeActivity activity = getCastActivity();
if (activity == null) return; if (activity == null || isInputError()) return;
String linkText = getLink(); String linkText = getLink();
if (linkText == null) throw new AssertionError(); if (linkText == null) throw new AssertionError();
if (OUR_LINK.equals("briar://" + linkText)) {
new AlertDialog.Builder(activity, R.style.BriarDialogTheme_Neutral)
.setMessage(
"Add the link you get from your contact, not your own link.")
.setNeutralButton(R.string.ok,
(dialog, which) -> {
linkInput.setText(null);
dialog.cancel();
})
.show();
return;
}
activity.addFakeRequest(contactNameInput.getText().toString(), activity.addFakeRequest(contactNameInput.getText().toString(),
linkText); linkText);

View File

@@ -31,7 +31,7 @@ import static android.widget.Toast.LENGTH_LONG;
import static android.widget.Toast.LENGTH_SHORT; import static android.widget.Toast.LENGTH_SHORT;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
public class ContactQrCodeInputFragment extends BaseFragment public class ContactQrCodeInputFragment extends BaseFragment
implements QrCodeDecoder.ResultCallback { implements QrCodeDecoder.ResultCallback {
@@ -134,7 +134,7 @@ public class ContactQrCodeInputFragment extends BaseFragment
public void onRequestPermissionsResult(int requestCode, public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) { @NonNull String[] permissions, @NonNull int[] grantResults) {
if (getContext() == null) return; if (getContext() == null) return;
if (requestCode == REQUEST_PERMISSION_CAMERA) { if (requestCode == REQUEST_PERMISSION_CAMERA_LOCATION) {
// If request is cancelled, the result arrays are empty. // If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && if (grantResults.length > 0 &&
grantResults[0] == PERMISSION_GRANTED) { grantResults[0] == PERMISSION_GRANTED) {
@@ -154,7 +154,7 @@ public class ContactQrCodeInputFragment extends BaseFragment
builder.show(); builder.show();
} else { } else {
Toast.makeText(getContext(), Toast.makeText(getContext(),
R.string.permission_camera_denied_toast, R.string.permission_camera_denied_body,
LENGTH_LONG).show(); LENGTH_LONG).show();
cancel(); cancel();
} }
@@ -163,7 +163,7 @@ public class ContactQrCodeInputFragment extends BaseFragment
} }
private void requestPermission() { private void requestPermission() {
requestPermissions(new String[] {CAMERA}, REQUEST_PERMISSION_CAMERA); requestPermissions(new String[] {CAMERA}, REQUEST_PERMISSION_CAMERA_LOCATION);
} }
@Nullable @Nullable

View File

@@ -24,6 +24,8 @@ import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static java.util.concurrent.TimeUnit.SECONDS;
public class PendingRequestsActivity extends BriarActivity public class PendingRequestsActivity extends BriarActivity
implements EventListener { implements EventListener {
@@ -57,12 +59,14 @@ public class PendingRequestsActivity extends BriarActivity
list = findViewById(R.id.list); list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this)); list.setLayoutManager(new LinearLayoutManager(this));
list.setAdapter(adapter); list.setAdapter(adapter);
list.setPERIODIC_UPDATE_MILLIS(SECONDS.toMillis(9));
} }
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
eventBus.addListener(this); eventBus.addListener(this);
list.startPeriodicUpdate();
runOnDbThread(() -> { runOnDbThread(() -> {
try { try {
Collection<PendingContact> contacts = Collection<PendingContact> contacts =
@@ -77,6 +81,7 @@ public class PendingRequestsActivity extends BriarActivity
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
list.stopPeriodicUpdate();
adapter.clear(); adapter.clear();
} }

View File

@@ -1,6 +1,7 @@
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.support.v7.widget.RecyclerView.ViewHolder; import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@@ -9,6 +10,7 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.view.TextAvatarView; import org.briarproject.briar.android.view.TextAvatarView;
import org.briarproject.briar.api.messaging.MessagingManager.PendingContact; import org.briarproject.briar.api.messaging.MessagingManager.PendingContact;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.briarproject.bramble.util.StringUtils.toUtf8; import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.util.UiUtils.formatDate; import static org.briarproject.briar.android.util.UiUtils.formatDate;
@@ -18,12 +20,14 @@ public class PendingRequestsViewHolder extends ViewHolder {
private final TextAvatarView avatar; private final TextAvatarView avatar;
private final TextView name; private final TextView name;
private final TextView time; private final TextView time;
private final TextView status;
public PendingRequestsViewHolder(View v) { public PendingRequestsViewHolder(View v) {
super(v); super(v);
avatar = v.findViewById(R.id.avatar); avatar = v.findViewById(R.id.avatar);
name = v.findViewById(R.id.name); name = v.findViewById(R.id.name);
time = v.findViewById(R.id.time); time = v.findViewById(R.id.time);
status = v.findViewById(R.id.status);
} }
public void bind(PendingContact item) { public void bind(PendingContact item) {
@@ -31,6 +35,15 @@ public class PendingRequestsViewHolder extends ViewHolder {
avatar.setBackgroundBytes(toUtf8(item.getName() + item.getTimestamp())); avatar.setBackgroundBytes(toUtf8(item.getName() + item.getTimestamp()));
name.setText(item.getName()); name.setText(item.getName());
time.setText(formatDate(time.getContext(), item.getTimestamp())); time.setText(formatDate(time.getContext(), item.getTimestamp()));
long diff = item.getAddAt() - System.currentTimeMillis();
Log.e("TEST", "diff: " + diff);
if (diff < SECONDS.toMillis(10)) {
status.setText("Adding contact…");
} else if (diff < SECONDS.toMillis(20)) {
status.setText("Connecting…");
} else if (diff < SECONDS.toMillis(30)) {
status.setText("Waiting for peer to come online…");
}
} }
} }

View File

@@ -28,6 +28,8 @@ public class BriarRecyclerView extends FrameLayout {
private final Handler handler = new Handler(Looper.getMainLooper()); private final Handler handler = new Handler(Looper.getMainLooper());
private long PERIODIC_UPDATE_MILLIS = MIN_DATE_RESOLUTION;
private RecyclerView recyclerView; private RecyclerView recyclerView;
private Group emptyState; private Group emptyState;
private AppCompatImageView emptyImage; private AppCompatImageView emptyImage;
@@ -215,9 +217,9 @@ public class BriarRecyclerView extends FrameLayout {
refresher = () -> { refresher = () -> {
Adapter adapter = recyclerView.getAdapter(); Adapter adapter = recyclerView.getAdapter();
adapter.notifyItemRangeChanged(0, adapter.getItemCount()); adapter.notifyItemRangeChanged(0, adapter.getItemCount());
handler.postDelayed(refresher, MIN_DATE_RESOLUTION); handler.postDelayed(refresher, PERIODIC_UPDATE_MILLIS);
}; };
handler.postDelayed(refresher, MIN_DATE_RESOLUTION); handler.postDelayed(refresher, PERIODIC_UPDATE_MILLIS);
} }
public void stopPeriodicUpdate() { public void stopPeriodicUpdate() {
@@ -227,4 +229,8 @@ public class BriarRecyclerView extends FrameLayout {
} }
} }
public void setPERIODIC_UPDATE_MILLIS(long millis) {
PERIODIC_UPDATE_MILLIS = millis;
}
} }

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,0C5.373,0 0,5.373 0,12c0,6.627 5.373,12 12,12 2.235,0 4.3203,-0.6235 6.1133,-1.6875 -0.266,-0.217 -0.4929,-0.4726 -0.6719,-0.7656C15.8354,22.4669 13.98,23 12,23 5.935,23 1,18.065 1,12 1,5.935 5.935,1 12,1c6.064,0 11,4.935 11,11 0,1.981 -0.5331,3.8344 -1.4531,5.4414 0.293,0.178 0.5486,0.4059 0.7656,0.6699C23.3765,16.3203 24,14.235 24,12 24,5.373 18.627,0 12,0ZM15,4a2,2 0,0 0,-2 2,2 2,0 0,0 2,2 2,2 0,0 0,2 -2,2 2,0 0,0 -2,-2zM12,5c-3.866,0 -7,3.134 -7,7 0,0.061 0.0078,0.1206 0.0098,0.1816C5.3198,12.0706 5.65,12 6,12 6,8.691 8.691,6 12,6 12,5.651 12.0706,5.3218 12.1816,5.0098 12.1206,5.0088 12.061,5 12,5ZM17.4922,7.668c-0.19,0.283 -0.435,0.5245 -0.707,0.7285C17.5442,9.4015 18,10.648 18,12c0,3.309 -2.691,6 -6,6 -1.354,0 -2.5985,-0.4568 -3.6035,-1.2148 -0.204,0.272 -0.4455,0.517 -0.7285,0.707C8.859,18.4342 10.362,19 12,19c3.866,0 7,-3.134 7,-7 0,-1.638 -0.5658,-3.14 -1.5078,-4.332zM12,10a2,2 0,0 0,-2 2,2 2,0 0,0 2,2 2,2 0,0 0,2 -2,2 2,0 0,0 -2,-2zM6,13a2,2 0,0 0,-2 2,2 2,0 0,0 2,2 2,2 0,0 0,2 -2,2 2,0 0,0 -2,-2zM20,18a2,2 0,0 0,-2 2,2 2,0 0,0 2,2 2,2 0,0 0,2 -2,2 2,0 0,0 -2,-2z"/>
</vector>

View File

@@ -45,7 +45,7 @@
app:hintEnabled="false" app:hintEnabled="false"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/copyButton"> app:layout_constraintTop_toBottomOf="@+id/divider">
<android.support.design.widget.TextInputEditText <android.support.design.widget.TextInputEditText
android:id="@+id/linkInput" android:id="@+id/linkInput"
@@ -104,6 +104,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0"
app:layout_constraintVertical_chainStyle="packed"/> app:layout_constraintVertical_chainStyle="packed"/>
<TextView <TextView
@@ -177,13 +178,19 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:enabled="false"
android:text="@string/add_contact_button" android:text="@string/add_contact_button"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contactNameLayout" app:layout_constraintTop_toBottomOf="@+id/contactNameLayout"/>
tools:enabled="true"/>
<View
android:id="@+id/divider"
style="@style/Divider.Horizontal"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/copyButton"/>
</android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
</ScrollView> </ScrollView>

View File

@@ -46,7 +46,8 @@
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/add_contact_remote_connecting" android:text="Waiting for peer to come online…"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/divider" app:layout_constraintBottom_toTopOf="@+id/divider"
app:layout_constraintEnd_toStartOf="@+id/time" app:layout_constraintEnd_toStartOf="@+id/time"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintHorizontal_bias="0.0"

View File

@@ -5,7 +5,7 @@
<item <item
android:id="@+id/action_add_contact_nearby" android:id="@+id/action_add_contact_nearby"
android:icon="@drawable/ic_add_nearby" android:icon="@drawable/ic_nearby"
android:orderInCategory="3" android:orderInCategory="3"
android:title="@string/add_contact_nearby_title" android:title="@string/add_contact_nearby_title"
app:showAsAction="never"/> app:showAsAction="never"/>

View File

@@ -164,17 +164,17 @@
<string name="connection_error_explanation">Please check that you\'re both connected to the same Wi-Fi network.</string> <string name="connection_error_explanation">Please check that you\'re both connected to the same Wi-Fi network.</string>
<string name="connection_error_feedback">If this problem persists, please <a href="feedback">send feedback</a> to help us improve the app.</string> <string name="connection_error_feedback">If this problem persists, please <a href="feedback">send feedback</a> to help us improve the app.</string>
<string name="add_contact_nearby_title">Add Contact Nearby</string> <string name="add_contact_nearby_title">Add contact nearby</string>
<string name="add_contact_remotely_title">Add Contact with Link</string> <string name="add_contact_remotely_title">Add contact remotely</string>
<string name="contact_name_hint">Give contact a nickname</string> <string name="contact_name_hint">Give peer a nickname</string>
<string name="contact_link_hint">Your contact\'s link</string> <string name="contact_link_hint">Enter peer\'s link</string>
<string name="paste_button">Paste</string> <string name="paste_button">Paste</string>
<string name="scan_qr_code_button">QR Code</string> <string name="scan_qr_code_button">QR Code</string>
<string name="add_contact_button">Add Contact</string> <string name="add_contact_button">Add peer as contact</string>
<string name="copy_button">Copy</string> <string name="copy_button">Copy</string>
<string name="share_button">Share</string> <string name="share_button">Share</string>
<string name="show_qr_code_button">QR Code</string> <string name="show_qr_code_button">QR Code</string>
<string name="send_link_instructions">Give this link to your contact:</string> <string name="send_link_instructions">Exchange links with your peer!\n\nYour link:</string>
<string name="link_clip_label">Briar link</string> <string name="link_clip_label">Briar link</string>
<string name="link_copied_toast">Link copied</string> <string name="link_copied_toast">Link copied</string>
<string name="pending_contact_requests_snackbar">"There are pending contact requests"</string> <string name="pending_contact_requests_snackbar">"There are pending contact requests"</string>

View File

@@ -16,15 +16,16 @@ import java.util.Collection;
public interface MessagingManager extends ConversationClient { public interface MessagingManager extends ConversationClient {
// TODO remove (only for prototype) // TODO remove (only for prototype)
void addNewPendingContact(String name, long timestamp) throws DbException; void addNewPendingContact(String name, long timestamp, long addAt) throws DbException;
void removePendingContact(String name, long timestamp) throws DbException; ContactId removePendingContact(String name, long timestamp, long addAt) throws DbException;
Collection<PendingContact> getPendingContacts() throws DbException; Collection<PendingContact> getPendingContacts() throws DbException;
class PendingContact { class PendingContact {
private final String name; private final String name;
private final long timestamp; private final long timestamp, addAt;
public PendingContact(String name, long timestamp) { public PendingContact(String name, long timestamp, long addAt) {
this.name = name; this.name = name;
this.timestamp = timestamp; this.timestamp = timestamp;
this.addAt = addAt;
} }
public String getName() { public String getName() {
return name; return name;
@@ -32,6 +33,9 @@ public interface MessagingManager extends ConversationClient {
public long getTimestamp() { public long getTimestamp() {
return timestamp; return timestamp;
} }
public long getAddAt() {
return addAt;
}
} }

View File

@@ -85,7 +85,7 @@ class MessagingManagerImpl extends ConversationClientImpl
private static final String PENDING_CONTACTS = "PENDING_CONTACTS"; private static final String PENDING_CONTACTS = "PENDING_CONTACTS";
@Override @Override
public void addNewPendingContact(String name, long timestamp) public void addNewPendingContact(String name, long timestamp, long addAt)
throws DbException { throws DbException {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
@@ -93,6 +93,7 @@ class MessagingManagerImpl extends ConversationClientImpl
BdfDictionary contact = new BdfDictionary(); BdfDictionary contact = new BdfDictionary();
contact.put("name", name); contact.put("name", name);
contact.put("timestamp", timestamp); contact.put("timestamp", timestamp);
contact.put("addAt", addAt);
list.add(contact); list.add(contact);
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
@@ -109,7 +110,7 @@ class MessagingManagerImpl extends ConversationClientImpl
} }
} }
@Override @Override
public void removePendingContact(String name, long timestamp) throws DbException { public ContactId removePendingContact(String name, long timestamp, long addAt) throws DbException {
Transaction txn = db.startTransaction(false); Transaction txn = db.startTransaction(false);
try { try {
BdfList list = getPendingContacts(txn); BdfList list = getPendingContacts(txn);
@@ -117,6 +118,7 @@ class MessagingManagerImpl extends ConversationClientImpl
BdfDictionary contactDict = new BdfDictionary(); BdfDictionary contactDict = new BdfDictionary();
contactDict.put("name", name); contactDict.put("name", name);
contactDict.put("timestamp", timestamp); contactDict.put("timestamp", timestamp);
contactDict.put("addAt", addAt);
list.remove(contactDict); list.remove(contactDict);
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID, Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
@@ -126,9 +128,11 @@ class MessagingManagerImpl extends ConversationClientImpl
clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta); clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta);
AuthorId local = identityManager.getLocalAuthor(txn).getId(); AuthorId local = identityManager.getLocalAuthor(txn).getId();
Author remote = authorFactory byte[] pubKey = new byte[MAX_PUBLIC_KEY_LENGTH];
.createAuthor(name, new byte[MAX_PUBLIC_KEY_LENGTH]); new Random().nextBytes(pubKey);
contactManager.addContact(txn, remote, local, false, true); Author remote = authorFactory.createAuthor(name, pubKey);
ContactId c =
contactManager.addContact(txn, remote, local, false, true);
Contact contact = Contact contact =
contactManager.getContact(txn, remote.getId(), local); contactManager.getContact(txn, remote.getId(), local);
@@ -137,6 +141,7 @@ class MessagingManagerImpl extends ConversationClientImpl
txn.attach(event); txn.attach(event);
db.commitTransaction(txn); db.commitTransaction(txn);
return c;
} catch (FormatException e) { } catch (FormatException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} finally { } finally {
@@ -152,7 +157,7 @@ class MessagingManagerImpl extends ConversationClientImpl
for (Object o : list) { for (Object o : list) {
BdfDictionary d = (BdfDictionary) o; BdfDictionary d = (BdfDictionary) o;
contacts.add(new PendingContact(d.getString("name"), contacts.add(new PendingContact(d.getString("name"),
d.getLong("timestamp"))); d.getLong("timestamp"), d.getLong("addAt")));
} }
db.commitTransaction(txn); db.commitTransaction(txn);
return contacts; return contacts;