mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 02:39:05 +01:00
Merge activities for adding contact nearby
and rename related classes to consolidate names
This commit is contained in:
@@ -342,7 +342,7 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.briarproject.briar.android.contact.add.nearby.ContactExchangeActivity"
|
||||
android:name="org.briarproject.briar.android.contact.add.nearby.AddNearbyContactActivity"
|
||||
android:label="@string/add_contact_title"
|
||||
android:parentActivityName="org.briarproject.briar.android.navdrawer.NavDrawerActivity"
|
||||
android:theme="@style/BriarTheme.NoActionBar">
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.briarproject.briar.android.account.DozeHelperModule;
|
||||
import org.briarproject.briar.android.account.LockManagerImpl;
|
||||
import org.briarproject.briar.android.account.SetupModule;
|
||||
import org.briarproject.briar.android.contact.ContactListModule;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeModule;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactModule;
|
||||
import org.briarproject.briar.android.forum.ForumModule;
|
||||
import org.briarproject.briar.android.introduction.IntroductionModule;
|
||||
import org.briarproject.briar.android.logging.LoggingModule;
|
||||
@@ -75,7 +75,7 @@ import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||
@Module(includes = {
|
||||
SetupModule.class,
|
||||
DozeHelperModule.class,
|
||||
ContactExchangeModule.class,
|
||||
AddNearbyContactModule.class,
|
||||
LoggingModule.class,
|
||||
LoginModule.class,
|
||||
NavDrawerModule.class,
|
||||
|
||||
@@ -21,11 +21,10 @@ import org.briarproject.briar.android.blog.RssFeedImportActivity;
|
||||
import org.briarproject.briar.android.blog.RssFeedManageActivity;
|
||||
import org.briarproject.briar.android.blog.WriteBlogPostActivity;
|
||||
import org.briarproject.briar.android.contact.ContactListFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeActivity;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeErrorFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.IntroFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.KeyAgreementActivity;
|
||||
import org.briarproject.briar.android.contact.add.nearby.KeyAgreementFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactActivity;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactErrorFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactIntroFragment;
|
||||
import org.briarproject.briar.android.contact.add.remote.AddContactActivity;
|
||||
import org.briarproject.briar.android.contact.add.remote.LinkExchangeFragment;
|
||||
import org.briarproject.briar.android.contact.add.remote.NicknameFragment;
|
||||
@@ -109,9 +108,7 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(PanicPreferencesActivity activity);
|
||||
|
||||
void inject(ContactExchangeActivity activity);
|
||||
|
||||
void inject(KeyAgreementActivity activity);
|
||||
void inject(AddNearbyContactActivity activity);
|
||||
|
||||
void inject(ConversationActivity activity);
|
||||
|
||||
@@ -209,9 +206,9 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(FeedFragment fragment);
|
||||
|
||||
void inject(IntroFragment fragment);
|
||||
|
||||
void inject(KeyAgreementFragment fragment);
|
||||
void inject(AddNearbyContactIntroFragment fragment);
|
||||
|
||||
void inject(AddNearbyContactFragment fragment);
|
||||
|
||||
void inject(LinkExchangeFragment fragment);
|
||||
|
||||
@@ -229,7 +226,7 @@ public interface ActivityComponent {
|
||||
|
||||
void inject(ScreenFilterDialogFragment fragment);
|
||||
|
||||
void inject(ContactExchangeErrorFragment fragment);
|
||||
void inject(AddNearbyContactErrorFragment fragment);
|
||||
|
||||
void inject(AliasDialogFragment aliasDialogFragment);
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactActivity;
|
||||
import org.briarproject.briar.android.contact.add.remote.AddContactActivity;
|
||||
import org.briarproject.briar.android.contact.add.remote.PendingContactListActivity;
|
||||
import org.briarproject.briar.android.conversation.ConversationActivity;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeActivity;
|
||||
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
|
||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||
|
||||
@@ -125,7 +125,8 @@ public class ContactListFragment extends BaseFragment
|
||||
switch (itemId) {
|
||||
case R.id.action_add_contact_nearby:
|
||||
Intent intent =
|
||||
new Intent(getContext(), ContactExchangeActivity.class);
|
||||
new Intent(getContext(),
|
||||
AddNearbyContactActivity.class);
|
||||
startActivity(intent);
|
||||
return;
|
||||
case R.id.action_add_contact_remotely:
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
abstract class AddContactState {
|
||||
|
||||
static class KeyAgreementListening extends AddContactState {
|
||||
final Bitmap qrCode;
|
||||
|
||||
KeyAgreementListening(Bitmap qrCode) {
|
||||
this.qrCode = qrCode;
|
||||
}
|
||||
}
|
||||
|
||||
static class QrCodeScanned extends AddContactState {
|
||||
}
|
||||
|
||||
static class KeyAgreementWaiting extends AddContactState {
|
||||
}
|
||||
|
||||
static class KeyAgreementStarted extends AddContactState {
|
||||
}
|
||||
|
||||
static class ContactExchangeStarted extends AddContactState {
|
||||
}
|
||||
|
||||
static class ContactExchangeFinished extends AddContactState {
|
||||
final ContactExchangeResult result;
|
||||
|
||||
ContactExchangeFinished(ContactExchangeResult result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
||||
static class Failed extends AddContactState {
|
||||
/**
|
||||
* Non-null if failed due to the scanned QR code version.
|
||||
* True if the app producing the code is too old.
|
||||
* False if the scanning app is too old.
|
||||
*/
|
||||
@Nullable
|
||||
final Boolean qrCodeTooOld;
|
||||
|
||||
Failed(@Nullable Boolean qrCodeTooOld) {
|
||||
this.qrCodeTooOld = qrCodeTooOld;
|
||||
}
|
||||
|
||||
Failed() {
|
||||
this(null);
|
||||
}
|
||||
}
|
||||
|
||||
abstract static class ContactExchangeResult {
|
||||
static class Success extends ContactExchangeResult {
|
||||
final Author remoteAuthor;
|
||||
|
||||
Success(Author remoteAuthor) {
|
||||
this.remoteAuthor = remoteAuthor;
|
||||
}
|
||||
}
|
||||
|
||||
static class Error extends ContactExchangeResult {
|
||||
@Nullable
|
||||
final Author duplicateAuthor;
|
||||
|
||||
Error(@Nullable Author duplicateAuthor) {
|
||||
this.duplicateAuthor = duplicateAuthor;
|
||||
}
|
||||
}
|
||||
} // end ContactExchangeResult
|
||||
|
||||
}
|
||||
@@ -6,13 +6,19 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.NullSafety;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.activity.BriarActivity;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeFinished;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||
|
||||
@@ -21,32 +27,32 @@ import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.UiThread;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
|
||||
import static android.bluetooth.BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.ACCEPTED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.REFUSED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.UNKNOWN;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.ACCEPTED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.UNKNOWN;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public abstract class KeyAgreementActivity extends BriarActivity
|
||||
public class AddNearbyContactActivity extends BriarActivity
|
||||
implements BaseFragmentListener {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(KeyAgreementActivity.class.getName());
|
||||
getLogger(AddNearbyContactActivity.class.getName());
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
protected ContactExchangeViewModel viewModel;
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
private AddNearbyContactPermissionManager permissionManager;
|
||||
|
||||
/**
|
||||
@@ -62,7 +68,7 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
public void injectActivity(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
viewModel = new ViewModelProvider(this, viewModelFactory)
|
||||
.get(ContactExchangeViewModel.class);
|
||||
.get(AddNearbyContactViewModel.class);
|
||||
permissionManager = new AddNearbyContactPermissionManager(this,
|
||||
viewModel.isBluetoothSupported());
|
||||
}
|
||||
@@ -73,9 +79,10 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
setContentView(R.layout.activity_fragment_container_toolbar);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
|
||||
NullSafety.requireNonNull(getSupportActionBar())
|
||||
.setDisplayHomeAsUpEnabled(true);
|
||||
if (state == null) {
|
||||
showInitialFragment(IntroFragment.newInstance());
|
||||
showInitialFragment(AddNearbyContactIntroFragment.newInstance());
|
||||
}
|
||||
IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
|
||||
bluetoothReceiver = new BluetoothStateReceiver();
|
||||
@@ -90,6 +97,10 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
viewModel.getShowQrCodeFragment().observeEvent(this, show -> {
|
||||
if (show) showQrCodeFragment();
|
||||
});
|
||||
requireNonNull(getSupportActionBar())
|
||||
.setTitle(R.string.add_contact_title);
|
||||
viewModel.getState()
|
||||
.observe(this, this::onAddContactStateChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,15 +131,6 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
if (bluetoothReceiver != null) unregisterReceiver(bluetoothReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int request, int result,
|
||||
@Nullable Intent data) {
|
||||
@@ -145,7 +147,15 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
String[] permissions, int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions,
|
||||
@@ -154,6 +164,16 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
grantResults, this::showQrCodeFragmentIfAllowed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (viewModel.getState().getValue() instanceof Failed) {
|
||||
// finish this activity when going back in failed state
|
||||
supportFinishAfterTransition();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private void requestBluetoothDiscoverable() {
|
||||
if (!viewModel.isBluetoothSupported()) {
|
||||
viewModel.bluetoothDecision = BluetoothDecision.NO_ADAPTER;
|
||||
@@ -174,7 +194,8 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
private void showQrCodeFragmentIfAllowed() {
|
||||
boolean continueClicked = // never set to null
|
||||
requireNonNull(viewModel.getWasContinueClicked().getValue());
|
||||
NullSafety.requireNonNull(
|
||||
viewModel.getWasContinueClicked().getValue());
|
||||
boolean permissionsGranted =
|
||||
permissionManager.areEssentialPermissionsGranted();
|
||||
if (isResumed && continueClicked && permissionsGranted) {
|
||||
@@ -197,8 +218,8 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
private void showQrCodeFragment() {
|
||||
// FIXME #824
|
||||
FragmentManager fm = getSupportFragmentManager();
|
||||
if (fm.findFragmentByTag(KeyAgreementFragment.TAG) == null) {
|
||||
BaseFragment f = KeyAgreementFragment.newInstance();
|
||||
if (fm.findFragmentByTag(AddNearbyContactFragment.TAG) == null) {
|
||||
BaseFragment f = AddNearbyContactFragment.newInstance();
|
||||
fm.beginTransaction()
|
||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||
.addToBackStack(f.getUniqueTag())
|
||||
@@ -206,6 +227,65 @@ public abstract class KeyAgreementActivity extends BriarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void onAddContactStateChanged(AddContactState state) {
|
||||
if (state instanceof ContactExchangeFinished) {
|
||||
ContactExchangeResult result =
|
||||
((ContactExchangeFinished) state).result;
|
||||
onContactExchangeResult(result);
|
||||
} else if (state instanceof Failed) {
|
||||
// Remove navigation icon, so user can't go back when failed
|
||||
// ErrorFragment will finish or relaunch this activity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setNavigationIcon(null);
|
||||
|
||||
Boolean qrCodeTooOld = ((Failed) state).qrCodeTooOld;
|
||||
onAddingContactFailed(qrCodeTooOld);
|
||||
}
|
||||
}
|
||||
|
||||
private void onContactExchangeResult(ContactExchangeResult result) {
|
||||
if (result instanceof ContactExchangeResult.Success) {
|
||||
Author remoteAuthor =
|
||||
((ContactExchangeResult.Success) result).remoteAuthor;
|
||||
String contactName = remoteAuthor.getName();
|
||||
String text = getString(R.string.contact_added_toast, contactName);
|
||||
Toast.makeText(this, text, LENGTH_LONG).show();
|
||||
supportFinishAfterTransition();
|
||||
} else if (result instanceof ContactExchangeResult.Error) {
|
||||
Author duplicateAuthor =
|
||||
((ContactExchangeResult.Error) result).duplicateAuthor;
|
||||
if (duplicateAuthor == null) {
|
||||
showErrorFragment();
|
||||
} else {
|
||||
String contactName = duplicateAuthor.getName();
|
||||
String text =
|
||||
getString(R.string.contact_already_exists, contactName);
|
||||
Toast.makeText(this, text, LENGTH_LONG).show();
|
||||
supportFinishAfterTransition();
|
||||
}
|
||||
} else throw new AssertionError();
|
||||
}
|
||||
|
||||
private void onAddingContactFailed(@Nullable Boolean qrCodeTooOld) {
|
||||
if (qrCodeTooOld == null) {
|
||||
showErrorFragment();
|
||||
} else {
|
||||
String msg;
|
||||
if (qrCodeTooOld) {
|
||||
msg = getString(R.string.qr_code_too_old,
|
||||
getString(R.string.app_name));
|
||||
} else {
|
||||
msg = getString(R.string.qr_code_too_new,
|
||||
getString(R.string.app_name));
|
||||
}
|
||||
showNextFragment(AddNearbyContactErrorFragment.newInstance(msg));
|
||||
}
|
||||
}
|
||||
|
||||
private void showErrorFragment() {
|
||||
showNextFragment(new AddNearbyContactErrorFragment());
|
||||
}
|
||||
|
||||
private class BluetoothStateReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
@@ -24,14 +24,14 @@ import static org.briarproject.briar.android.util.UiUtils.onSingleLinkClick;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class ContactExchangeErrorFragment extends BaseFragment {
|
||||
public class AddNearbyContactErrorFragment extends BaseFragment {
|
||||
|
||||
public static final String TAG =
|
||||
ContactExchangeErrorFragment.class.getName();
|
||||
AddNearbyContactErrorFragment.class.getName();
|
||||
private static final String ERROR_MSG = "errorMessage";
|
||||
|
||||
public static ContactExchangeErrorFragment newInstance(String errorMsg) {
|
||||
ContactExchangeErrorFragment f = new ContactExchangeErrorFragment();
|
||||
public static AddNearbyContactErrorFragment newInstance(String errorMsg) {
|
||||
AddNearbyContactErrorFragment f = new AddNearbyContactErrorFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ERROR_MSG, errorMsg);
|
||||
f.setArguments(args);
|
||||
@@ -72,7 +72,7 @@ public class ContactExchangeErrorFragment extends BaseFragment {
|
||||
tryAgain.setOnClickListener(view -> {
|
||||
// Recreate the activity so we return to the intro fragment
|
||||
FragmentActivity activity = requireActivity();
|
||||
Intent i = new Intent(activity, ContactExchangeActivity.class);
|
||||
Intent i = new Intent(activity, AddNearbyContactActivity.class);
|
||||
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
|
||||
activity.startActivity(i);
|
||||
});
|
||||
@@ -14,11 +14,11 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.ContactExchangeStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.Failed;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.QrCodeScanned;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.Failed;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.QrCodeScanned;
|
||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||
import org.briarproject.briar.android.view.QrCodeView;
|
||||
|
||||
@@ -42,26 +42,26 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class KeyAgreementFragment extends BaseFragment
|
||||
public class AddNearbyContactFragment extends BaseFragment
|
||||
implements QrCodeView.FullscreenListener {
|
||||
|
||||
static final String TAG = KeyAgreementFragment.class.getName();
|
||||
static final String TAG = AddNearbyContactFragment.class.getName();
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(TAG);
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private ContactExchangeViewModel viewModel;
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
private CameraView cameraView;
|
||||
private LinearLayout cameraOverlay;
|
||||
private View statusView;
|
||||
private QrCodeView qrCodeView;
|
||||
private TextView status;
|
||||
|
||||
public static KeyAgreementFragment newInstance() {
|
||||
public static AddNearbyContactFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
KeyAgreementFragment fragment = new KeyAgreementFragment();
|
||||
AddNearbyContactFragment fragment = new AddNearbyContactFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class KeyAgreementFragment extends BaseFragment
|
||||
public void injectFragment(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||
.get(ContactExchangeViewModel.class);
|
||||
.get(AddNearbyContactViewModel.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -93,7 +93,7 @@ public class KeyAgreementFragment extends BaseFragment
|
||||
qrCodeView.setFullscreenListener(this);
|
||||
|
||||
viewModel.getState().observe(getViewLifecycleOwner(),
|
||||
this::onContactAddingStateChanged);
|
||||
this::onAddContactStateChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,10 +153,10 @@ public class KeyAgreementFragment extends BaseFragment
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void onContactAddingStateChanged(ContactAddingState state) {
|
||||
if (state instanceof ContactAddingState.KeyAgreementListening) {
|
||||
private void onAddContactStateChanged(AddContactState state) {
|
||||
if (state instanceof AddContactState.KeyAgreementListening) {
|
||||
Bitmap qrCode =
|
||||
((ContactAddingState.KeyAgreementListening) state).qrCode;
|
||||
((AddContactState.KeyAgreementListening) state).qrCode;
|
||||
qrCodeView.setQrCode(qrCode);
|
||||
} else if (state instanceof QrCodeScanned) {
|
||||
try {
|
||||
@@ -21,20 +21,21 @@ import static android.view.View.FOCUS_DOWN;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class IntroFragment extends BaseFragment {
|
||||
public class AddNearbyContactIntroFragment extends BaseFragment {
|
||||
|
||||
public static final String TAG = IntroFragment.class.getName();
|
||||
public static final String TAG = AddNearbyContactIntroFragment.class.getName();
|
||||
|
||||
@Inject
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private ContactExchangeViewModel viewModel;
|
||||
private AddNearbyContactViewModel viewModel;
|
||||
|
||||
private ScrollView scrollView;
|
||||
|
||||
public static IntroFragment newInstance() {
|
||||
public static AddNearbyContactIntroFragment newInstance() {
|
||||
Bundle args = new Bundle();
|
||||
IntroFragment fragment = new IntroFragment();
|
||||
AddNearbyContactIntroFragment
|
||||
fragment = new AddNearbyContactIntroFragment();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
@@ -43,7 +44,7 @@ public class IntroFragment extends BaseFragment {
|
||||
public void injectFragment(ActivityComponent component) {
|
||||
component.inject(this);
|
||||
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||
.get(ContactExchangeViewModel.class);
|
||||
.get(AddNearbyContactViewModel.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -8,12 +8,12 @@ import dagger.Module;
|
||||
import dagger.multibindings.IntoMap;
|
||||
|
||||
@Module
|
||||
public abstract class ContactExchangeModule {
|
||||
public abstract class AddNearbyContactModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(ContactExchangeViewModel.class)
|
||||
@ViewModelKey(AddNearbyContactViewModel.class)
|
||||
abstract ViewModel bindContactExchangeViewModel(
|
||||
ContactExchangeViewModel contactExchangeViewModel);
|
||||
AddNearbyContactViewModel addNearbyContactViewModel);
|
||||
|
||||
}
|
||||
@@ -40,13 +40,13 @@ import org.briarproject.bramble.api.plugin.TransportId;
|
||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
||||
import org.briarproject.bramble.api.plugin.event.TransportStateEvent;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.ContactExchangeFinished;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.ContactExchangeStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.KeyAgreementListening;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeResult.Error;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactExchangeResult.Success;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeFinished;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult.Error;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeResult.Success;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.ContactExchangeStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementListening;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementStarted;
|
||||
import org.briarproject.briar.android.contact.add.nearby.AddContactState.KeyAgreementWaiting;
|
||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||
|
||||
@@ -75,15 +75,15 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
|
||||
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.REFUSED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.ContactExchangeViewModel.BluetoothDecision.UNKNOWN;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED;
|
||||
import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.UNKNOWN;
|
||||
|
||||
@NotNullByDefault
|
||||
class ContactExchangeViewModel extends AndroidViewModel
|
||||
class AddNearbyContactViewModel extends AndroidViewModel
|
||||
implements EventListener, QrCodeDecoder.ResultCallback {
|
||||
|
||||
private static final Logger LOG =
|
||||
getLogger(ContactExchangeViewModel.class.getName());
|
||||
getLogger(AddNearbyContactViewModel.class.getName());
|
||||
|
||||
enum BluetoothDecision {
|
||||
/**
|
||||
@@ -135,7 +135,7 @@ class ContactExchangeViewModel extends AndroidViewModel
|
||||
new MutableLiveEvent<>();
|
||||
private final MutableLiveEvent<TransportId> transportStateChanged =
|
||||
new MutableLiveEvent<>();
|
||||
private final MutableLiveData<ContactAddingState> state =
|
||||
private final MutableLiveData<AddContactState> state =
|
||||
new MutableLiveData<>();
|
||||
|
||||
final QrCodeDecoder qrCodeDecoder;
|
||||
@@ -164,7 +164,7 @@ class ContactExchangeViewModel extends AndroidViewModel
|
||||
private volatile boolean gotLocalPayload = false, gotRemotePayload = false;
|
||||
|
||||
@Inject
|
||||
ContactExchangeViewModel(Application app,
|
||||
AddNearbyContactViewModel(Application app,
|
||||
EventBus eventBus,
|
||||
@IoExecutor Executor ioExecutor,
|
||||
PluginManager pluginManager,
|
||||
@@ -336,11 +336,11 @@ class ContactExchangeViewModel extends AndroidViewModel
|
||||
} else if (e instanceof KeyAgreementAbortedEvent) {
|
||||
LOG.info("KeyAgreementAbortedEvent received");
|
||||
resetPayloadFlags();
|
||||
state.setValue(new ContactAddingState.Failed());
|
||||
state.setValue(new AddContactState.Failed());
|
||||
} else if (e instanceof KeyAgreementFailedEvent) {
|
||||
LOG.info("KeyAgreementFailedEvent received");
|
||||
resetPayloadFlags();
|
||||
state.setValue(new ContactAddingState.Failed());
|
||||
state.setValue(new AddContactState.Failed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,16 +377,16 @@ class ContactExchangeViewModel extends AndroidViewModel
|
||||
Payload remotePayload = payloadParser.parse(payloadBytes);
|
||||
gotRemotePayload = true;
|
||||
requireNonNull(task).connectAndRunProtocol(remotePayload);
|
||||
state.postValue(new ContactAddingState.QrCodeScanned());
|
||||
state.postValue(new AddContactState.QrCodeScanned());
|
||||
} catch (UnsupportedVersionException e) {
|
||||
resetPayloadFlags();
|
||||
state.postValue(new ContactAddingState.Failed(e.isTooOld()));
|
||||
state.postValue(new AddContactState.Failed(e.isTooOld()));
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
LOG.log(WARNING, "QR Code Invalid", e);
|
||||
Toast.makeText(getApplication(), R.string.qr_code_invalid,
|
||||
LENGTH_LONG).show();
|
||||
resetPayloadFlags();
|
||||
state.postValue(new ContactAddingState.Failed());
|
||||
state.postValue(new AddContactState.Failed());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +448,7 @@ class ContactExchangeViewModel extends AndroidViewModel
|
||||
return showQrCodeFragment;
|
||||
}
|
||||
|
||||
LiveData<ContactAddingState> getState() {
|
||||
LiveData<AddContactState> getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
abstract class ContactAddingState {
|
||||
|
||||
static class KeyAgreementListening extends ContactAddingState {
|
||||
final Bitmap qrCode;
|
||||
|
||||
KeyAgreementListening(Bitmap qrCode) {
|
||||
this.qrCode = qrCode;
|
||||
}
|
||||
}
|
||||
|
||||
static class QrCodeScanned extends ContactAddingState {
|
||||
}
|
||||
|
||||
static class KeyAgreementWaiting extends ContactAddingState {
|
||||
}
|
||||
|
||||
static class KeyAgreementStarted extends ContactAddingState {
|
||||
}
|
||||
|
||||
static class ContactExchangeStarted extends ContactAddingState {
|
||||
}
|
||||
|
||||
static class ContactExchangeFinished extends ContactAddingState {
|
||||
final ContactExchangeResult result;
|
||||
|
||||
ContactExchangeFinished(ContactExchangeResult result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
||||
static class Failed extends ContactAddingState {
|
||||
/**
|
||||
* Non-null if failed due to the scanned QR code version.
|
||||
* True if the app producing the code is too old.
|
||||
* False if the scanning app is too old.
|
||||
*/
|
||||
@Nullable
|
||||
final Boolean qrCodeTooOld;
|
||||
|
||||
Failed(@Nullable Boolean qrCodeTooOld) {
|
||||
this.qrCodeTooOld = qrCodeTooOld;
|
||||
}
|
||||
|
||||
Failed() {
|
||||
this(null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.ContactExchangeFinished;
|
||||
import org.briarproject.briar.android.contact.add.nearby.ContactAddingState.Failed;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class ContactExchangeActivity extends KeyAgreementActivity {
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle state) {
|
||||
super.onCreate(state);
|
||||
requireNonNull(getSupportActionBar())
|
||||
.setTitle(R.string.add_contact_title);
|
||||
viewModel.getState()
|
||||
.observe(this, this::onContactAddingStateChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (viewModel.getState().getValue() instanceof Failed) {
|
||||
// finish this activity when going back in failed state
|
||||
supportFinishAfterTransition();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
|
||||
private void onContactAddingStateChanged(ContactAddingState state) {
|
||||
if (state instanceof ContactExchangeFinished) {
|
||||
ContactExchangeResult result =
|
||||
((ContactExchangeFinished) state).result;
|
||||
onContactExchangeResult(result);
|
||||
} else if (state instanceof Failed) {
|
||||
// Remove navigation icon, so user can't go back when failed
|
||||
// ErrorFragment will finish or relaunch this activity
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
toolbar.setNavigationIcon(null);
|
||||
|
||||
Boolean qrCodeTooOld = ((Failed) state).qrCodeTooOld;
|
||||
onAddingContactFailed(qrCodeTooOld);
|
||||
}
|
||||
}
|
||||
|
||||
private void onContactExchangeResult(ContactExchangeResult result) {
|
||||
if (result instanceof ContactExchangeResult.Success) {
|
||||
Author remoteAuthor =
|
||||
((ContactExchangeResult.Success) result).remoteAuthor;
|
||||
String contactName = remoteAuthor.getName();
|
||||
String text = getString(R.string.contact_added_toast, contactName);
|
||||
Toast.makeText(this, text, LENGTH_LONG).show();
|
||||
supportFinishAfterTransition();
|
||||
} else if (result instanceof ContactExchangeResult.Error) {
|
||||
Author duplicateAuthor =
|
||||
((ContactExchangeResult.Error) result).duplicateAuthor;
|
||||
if (duplicateAuthor == null) {
|
||||
showErrorFragment();
|
||||
} else {
|
||||
String contactName = duplicateAuthor.getName();
|
||||
String text =
|
||||
getString(R.string.contact_already_exists, contactName);
|
||||
Toast.makeText(this, text, LENGTH_LONG).show();
|
||||
supportFinishAfterTransition();
|
||||
}
|
||||
} else throw new AssertionError();
|
||||
}
|
||||
|
||||
private void onAddingContactFailed(@Nullable Boolean qrCodeTooOld) {
|
||||
if (qrCodeTooOld == null) {
|
||||
showErrorFragment();
|
||||
} else {
|
||||
String msg;
|
||||
if (qrCodeTooOld) {
|
||||
msg = getString(R.string.qr_code_too_old,
|
||||
getString(R.string.app_name));
|
||||
} else {
|
||||
msg = getString(R.string.qr_code_too_new,
|
||||
getString(R.string.app_name));
|
||||
}
|
||||
showNextFragment(ContactExchangeErrorFragment.newInstance(msg));
|
||||
}
|
||||
}
|
||||
|
||||
private void showErrorFragment() {
|
||||
showNextFragment(new ContactExchangeErrorFragment());
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package org.briarproject.briar.android.contact.add.nearby;
|
||||
|
||||
import org.briarproject.bramble.api.identity.Author;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
@Immutable
|
||||
@NotNullByDefault
|
||||
abstract class ContactExchangeResult {
|
||||
|
||||
static class Success extends ContactExchangeResult {
|
||||
final Author remoteAuthor;
|
||||
|
||||
Success(Author remoteAuthor) {
|
||||
this.remoteAuthor = remoteAuthor;
|
||||
}
|
||||
}
|
||||
|
||||
static class Error extends ContactExchangeResult {
|
||||
@Nullable
|
||||
final Author duplicateAuthor;
|
||||
|
||||
Error(@Nullable Author duplicateAuthor) {
|
||||
this.duplicateAuthor = duplicateAuthor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user