diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index 730880e1d..79bca962b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -17,8 +17,10 @@ import org.briarproject.briar.android.blog.RssFeedManageActivity; import org.briarproject.briar.android.blog.WriteBlogPostActivity; import org.briarproject.briar.android.contact.ContactLinkInputActivity; import org.briarproject.briar.android.contact.ContactLinkOutputActivity; +import org.briarproject.briar.android.contact.ContactLinkOutputFragment; import org.briarproject.briar.android.contact.ContactListFragment; import org.briarproject.briar.android.contact.ContactModule; +import org.briarproject.briar.android.contact.ContactQrCodeOutputFragment; import org.briarproject.briar.android.contact.ConversationActivity; import org.briarproject.briar.android.contact.PendingRequestsActivity; import org.briarproject.briar.android.forum.CreateForumActivity; @@ -173,6 +175,8 @@ public interface ActivityComponent { void inject(ContactLinkOutputActivity activity); void inject(ContactLinkInputActivity activity); void inject(PendingRequestsActivity activity); + void inject(ContactLinkOutputFragment activity); + void inject(ContactQrCodeOutputFragment activity); // Fragments void inject(AuthorNameFragment fragment); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputActivity.java index 05aa748d7..87b594e03 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputActivity.java @@ -1,27 +1,23 @@ package org.briarproject.briar.android.contact; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Intent; import android.os.Bundle; import android.support.v7.app.ActionBar; +import android.view.Menu; +import android.view.MenuInflater; import android.view.MenuItem; -import android.widget.Button; -import android.widget.TextView; -import android.widget.Toast; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; +import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; import javax.annotation.Nullable; -import static android.content.Intent.ACTION_SEND; -import static android.content.Intent.EXTRA_TEXT; -import static android.widget.Toast.LENGTH_SHORT; -import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; +public class ContactLinkOutputActivity extends BriarActivity implements + BaseFragmentListener { -public class ContactLinkOutputActivity extends BriarActivity { + private Menu menu; + private boolean showQrCode = true; @Override public void injectActivity(ActivityComponent component) { @@ -32,38 +28,25 @@ public class ContactLinkOutputActivity extends BriarActivity { public void onCreate(@Nullable Bundle state) { super.onCreate(state); - setContentView(R.layout.activity_contact_link_output); + setContentView(R.layout.activity_fragment_container); ActionBar ab = getSupportActionBar(); if (ab != null) { ab.setDisplayHomeAsUpEnabled(true); } - String link = "briar://" + getRandomBase32String(64); + if (state == null) { + showInitialFragment(new ContactQrCodeOutputFragment()); + } + } - TextView linkView = findViewById(R.id.linkView); - linkView.setText(link); - - ClipboardManager clipboard = (ClipboardManager) - getSystemService(CLIPBOARD_SERVICE); - if (clipboard == null) throw new AssertionError(); - ClipData clip = ClipData.newPlainText( - getString(R.string.link_clip_label), link); - - Button copyButton = findViewById(R.id.copyButton); - copyButton.setOnClickListener(v -> { - clipboard.setPrimaryClip(clip); - Toast.makeText(this, R.string.link_copied_toast, LENGTH_SHORT) - .show(); - }); - - Button shareButton = findViewById(R.id.shareButton); - shareButton.setOnClickListener(v -> { - Intent i = new Intent(ACTION_SEND); - i.putExtra(EXTRA_TEXT, link); - i.setType("text/plain"); - startActivity(i); - }); + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.contact_output_actions, menu); + menu.findItem(R.id.action_switch) + .setTitle(showQrCode ? R.string.show_link : R.string.show_code); + return super.onCreateOptionsMenu(menu); } @Override @@ -72,9 +55,21 @@ public class ContactLinkOutputActivity extends BriarActivity { case android.R.id.home: onBackPressed(); return true; + case R.id.action_switch: + switchFragment(); + return true; default: return super.onOptionsItemSelected(item); } } + private void switchFragment() { + if (showQrCode) { + showInitialFragment(new ContactLinkOutputFragment()); + } else { + showInitialFragment(new ContactQrCodeOutputFragment()); + } + showQrCode = !showQrCode; + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputFragment.java new file mode 100644 index 000000000..140f0f9c0 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactLinkOutputFragment.java @@ -0,0 +1,82 @@ +package org.briarproject.briar.android.contact; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; + +import javax.annotation.Nullable; + +import static android.content.Context.CLIPBOARD_SERVICE; +import static android.content.Intent.ACTION_SEND; +import static android.content.Intent.EXTRA_TEXT; +import static android.widget.Toast.LENGTH_SHORT; +import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; + +@NotNullByDefault +public class ContactLinkOutputFragment extends BaseFragment { + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + + getActivity().setTitle(R.string.send_link_title); + + View v = inflater.inflate(R.layout.fragment_contact_link_output, + container, false); + + String link = "briar://" + getRandomBase32String(64); + + TextView linkView = v.findViewById(R.id.linkView); + linkView.setText(link); + + ClipboardManager clipboard = (ClipboardManager) + getContext().getSystemService(CLIPBOARD_SERVICE); + if (clipboard == null) throw new AssertionError(); + ClipData clip = ClipData.newPlainText( + getString(R.string.link_clip_label), link); + + Button copyButton = v.findViewById(R.id.copyButton); + copyButton.setOnClickListener(view -> { + clipboard.setPrimaryClip(clip); + Toast.makeText(getContext(), R.string.link_copied_toast, + LENGTH_SHORT).show(); + }); + + Button shareButton = v.findViewById(R.id.shareButton); + shareButton.setOnClickListener(view -> { + Intent i = new Intent(ACTION_SEND); + i.putExtra(EXTRA_TEXT, link); + i.setType("text/plain"); + startActivity(i); + }); + return v; + } + + public static final String TAG = ContactLinkOutputFragment.class.getName(); + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + +} 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 new file mode 100644 index 000000000..54424740d --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactQrCodeOutputFragment.java @@ -0,0 +1,68 @@ +package org.briarproject.briar.android.contact; + +import android.graphics.Bitmap; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.fragment.BaseFragment; +import org.briarproject.briar.android.view.QrCodeView; + +import javax.annotation.Nullable; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; +import static org.briarproject.bramble.util.StringUtils.getRandomBase32String; +import static org.briarproject.briar.android.keyagreement.QrCodeUtils.createQrCode; + +@NotNullByDefault +public class ContactQrCodeOutputFragment extends BaseFragment + implements QrCodeView.FullscreenListener { + + private View linkIntro; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + + getActivity().setTitle(R.string.send_code_title); + + View v = inflater.inflate(R.layout.fragment_contact_qr_code_output, + container, false); + linkIntro = v.findViewById(R.id.linkIntro); + + String link = "briar://" + getRandomBase32String(64); + DisplayMetrics dm = getResources().getDisplayMetrics(); + Bitmap qrCode = createQrCode(dm, link); + QrCodeView qrCodeView = v.findViewById(R.id.qrCodeView); + qrCodeView.setQrCode(qrCode); + qrCodeView.setFullscreenListener(this); + + return v; + } + + public static final String TAG = ContactQrCodeOutputFragment.class.getName(); + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + @Override + public void setFullscreen(boolean fullscreen) { + linkIntro.setVisibility(fullscreen ? GONE : VISIBLE); + } + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java index 617f84b99..658cffa1e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/keyagreement/QrCodeUtils.java @@ -21,13 +21,13 @@ import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.util.LogUtils.logException; @NotNullByDefault -class QrCodeUtils { +public class QrCodeUtils { private static final Logger LOG = Logger.getLogger(QrCodeUtils.class.getName()); @Nullable - static Bitmap createQrCode(DisplayMetrics dm, String input) { + public static Bitmap createQrCode(DisplayMetrics dm, String input) { int smallestDimen = Math.min(dm.widthPixels, dm.heightPixels); try { // Generate QR code diff --git a/briar-android/src/main/res/drawable/ic_qr_code.xml b/briar-android/src/main/res/drawable/ic_qr_code.xml new file mode 100644 index 000000000..513193b4a --- /dev/null +++ b/briar-android/src/main/res/drawable/ic_qr_code.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/briar-android/src/main/res/layout/activity_contact_link_output.xml b/briar-android/src/main/res/layout/fragment_contact_link_output.xml similarity index 100% rename from briar-android/src/main/res/layout/activity_contact_link_output.xml rename to briar-android/src/main/res/layout/fragment_contact_link_output.xml diff --git a/briar-android/src/main/res/layout/fragment_contact_qr_code_output.xml b/briar-android/src/main/res/layout/fragment_contact_qr_code_output.xml new file mode 100644 index 000000000..be60f36f5 --- /dev/null +++ b/briar-android/src/main/res/layout/fragment_contact_qr_code_output.xml @@ -0,0 +1,38 @@ + + + + + + + + diff --git a/briar-android/src/main/res/menu/contact_list_actions.xml b/briar-android/src/main/res/menu/contact_list_actions.xml index 27cb4bc52..9940051e4 100644 --- a/briar-android/src/main/res/menu/contact_list_actions.xml +++ b/briar-android/src/main/res/menu/contact_list_actions.xml @@ -14,11 +14,17 @@ android:icon="@drawable/ic_link" android:title="@string/open_link_title" app:showAsAction="never"/> - + + \ No newline at end of file diff --git a/briar-android/src/main/res/menu/contact_output_actions.xml b/briar-android/src/main/res/menu/contact_output_actions.xml new file mode 100644 index 000000000..2139209d2 --- /dev/null +++ b/briar-android/src/main/res/menu/contact_output_actions.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index fff763b6a..26445d0ee 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -153,6 +153,9 @@ Add Contact Nearby Open Link Send My Link + Send My QR Code + Show Link + Show QR code Contact name Contact link Paste @@ -160,6 +163,7 @@ Share Copy Send this link to your contact: + Let your contact scan this QR code with Briar: Briar link Link copied "There are pending contact requests"