diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeActivity.java index b0e42b160..ef6e1c4aa 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeActivity.java @@ -27,11 +27,13 @@ import static android.content.Intent.ACTION_VIEW; import static android.content.Intent.EXTRA_TEXT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.os.SystemClock.elapsedRealtime; +import static java.lang.String.CASE_INSENSITIVE_ORDER; import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; import static org.briarproject.bramble.util.LogUtils.logException; +import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; public class ContactLinkExchangeActivity extends BriarActivity implements BaseFragmentListener { @@ -39,6 +41,8 @@ public class ContactLinkExchangeActivity extends BriarActivity implements private static final Logger LOG = Logger.getLogger(ContactLinkExchangeActivity.class.getName()); + static final String OUR_LINK = "briar://" + getRandomBase32String(64); + @Inject LifecycleManager lifecycleManager; @Inject @@ -110,6 +114,7 @@ public class ContactLinkExchangeActivity extends BriarActivity implements } void linkScanned(@Nullable String link) { + // FIXME: Contact name is lost showNextFragment(ContactLinkExchangeFragment.newInstance(link)); } @@ -117,7 +122,7 @@ public class ContactLinkExchangeActivity extends BriarActivity implements showNextFragment(new ContactQrCodeOutputFragment()); } - void addFakeRequest(String name) { + void addFakeRequest(String name, String link) { long timestamp = clock.currentTimeMillis(); try { messagingManager.addNewPendingContact(name, timestamp); @@ -127,8 +132,10 @@ public class ContactLinkExchangeActivity extends BriarActivity implements AlarmManager alarmManager = (AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE)); + double random = getPseudoRandom(link, OUR_LINK); long m = MINUTES.toMillis(1); - long fromNow = (long) (-m * Math.log(Math.random())); + long fromNow = (long) (-m * Math.log(random)); + LOG.info("Delay " + fromNow + " ms based on seed " + random); long triggerAt = elapsedRealtime() + fromNow; Intent i = new Intent(this, ContactLinkExchangeActivity.class); @@ -141,6 +148,24 @@ public class ContactLinkExchangeActivity extends BriarActivity implements alarmManager.set(ELAPSED_REALTIME, triggerAt, pendingIntent); } + /** + * Returns a pseudo-random value greater than or equal to 0 and less than 1, + * approximately uniformly distributed, based on the given strings. The + * same value is returned if the strings are swapped. + */ + private double getPseudoRandom(String a, String b) { + String first, second; + if (CASE_INSENSITIVE_ORDER.compare(a, b) < 0) { + first = a; + second = b; + } else { + first = b; + second = a; + } + int hash = (first + second).hashCode() & Integer.MAX_VALUE; + return hash / (1.0 + Integer.MAX_VALUE); + } + private void removeFakeRequest(String name, long timestamp) { if (lifecycleManager.getLifecycleState() != RUNNING) { LOG.info("Lifecycle not started, not adding contact " + name); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeFragment.java index a7f4c23bd..9b12a984b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkExchangeFragment.java @@ -30,7 +30,7 @@ import static android.support.v4.graphics.drawable.DrawableCompat.setTint; import static android.support.v4.graphics.drawable.DrawableCompat.wrap; import static android.widget.Toast.LENGTH_SHORT; import static java.util.Objects.requireNonNull; -import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; +import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK; import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute; public class ContactLinkExchangeFragment extends BaseFragment @@ -114,13 +114,11 @@ public class ContactLinkExchangeFragment extends BaseFragment if (activity != null) activity.scanCode(); }); - String link = "briar://" + getRandomBase32String(64); - TextView linkView = v.findViewById(R.id.linkView); - linkView.setText(link); + linkView.setText(OUR_LINK); ClipData clip = ClipData.newPlainText( - getString(R.string.link_clip_label), link); + getString(R.string.link_clip_label), OUR_LINK); Button copyButton = v.findViewById(R.id.copyButton); copyButton.setOnClickListener(view -> { @@ -132,7 +130,7 @@ public class ContactLinkExchangeFragment extends BaseFragment Button shareButton = v.findViewById(R.id.shareButton); shareButton.setOnClickListener(view -> { Intent i = new Intent(ACTION_SEND); - i.putExtra(EXTRA_TEXT, link); + i.putExtra(EXTRA_TEXT, OUR_LINK); i.setType("text/plain"); startActivity(i); }); @@ -180,7 +178,8 @@ public class ContactLinkExchangeFragment extends BaseFragment ContactLinkExchangeActivity activity = getCastActivity(); if (activity == null) return; - activity.addFakeRequest(contactNameInput.getText().toString()); + activity.addFakeRequest(contactNameInput.getText().toString(), + linkInput.getText().toString()); Intent intent = new Intent(activity, PendingRequestsActivity.class); startActivity(intent); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactQrCodeOutputFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactQrCodeOutputFragment.java index 51588f5ff..4b241a937 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactQrCodeOutputFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactQrCodeOutputFragment.java @@ -15,7 +15,7 @@ import org.briarproject.briar.android.view.QrCodeView; import javax.annotation.Nullable; -import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; +import static org.briarproject.briar.android.contact.ContactLinkExchangeActivity.OUR_LINK; import static org.briarproject.briar.android.keyagreement.QrCodeUtils.createQrCode; public class ContactQrCodeOutputFragment extends BaseFragment { @@ -44,9 +44,8 @@ public class ContactQrCodeOutputFragment extends BaseFragment { View v = inflater.inflate(R.layout.fragment_contact_qr_code_output, container, false); - String link = "briar://" + getRandomBase32String(64); DisplayMetrics dm = getResources().getDisplayMetrics(); - Bitmap qrCode = createQrCode(dm, link); + Bitmap qrCode = createQrCode(dm, OUR_LINK); QrCodeView qrCodeView = v.findViewById(R.id.qrCodeView); qrCodeView.setQrCode(qrCode);