mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Make a ReturnShardFragment, based on ContactExchangeFragment
This commit is contained in:
@@ -91,6 +91,7 @@ import org.briarproject.briar.android.socialbackup.ShardsSentFragment;
|
|||||||
import org.briarproject.briar.android.socialbackup.ThresholdSelectorFragment;
|
import org.briarproject.briar.android.socialbackup.ThresholdSelectorFragment;
|
||||||
import org.briarproject.briar.android.socialbackup.creation.CreateBackupModule;
|
import org.briarproject.briar.android.socialbackup.creation.CreateBackupModule;
|
||||||
import org.briarproject.briar.android.socialbackup.recover.ReturnShardActivity;
|
import org.briarproject.briar.android.socialbackup.recover.ReturnShardActivity;
|
||||||
|
import org.briarproject.briar.android.socialbackup.recover.ReturnShardFragment;
|
||||||
import org.briarproject.briar.android.splash.SplashScreenActivity;
|
import org.briarproject.briar.android.splash.SplashScreenActivity;
|
||||||
import org.briarproject.briar.android.test.TestDataActivity;
|
import org.briarproject.briar.android.test.TestDataActivity;
|
||||||
|
|
||||||
@@ -276,4 +277,6 @@ public interface ActivityComponent {
|
|||||||
void inject(ExistingBackupFragment existingBackupFragment);
|
void inject(ExistingBackupFragment existingBackupFragment);
|
||||||
|
|
||||||
void inject(NewOrRecoverFragment newOrRecoverFragment);
|
void inject(NewOrRecoverFragment newOrRecoverFragment);
|
||||||
|
|
||||||
|
void inject(ReturnShardFragment returnShardFragment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.briarproject.briar.android.contact.add.nearby;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
class CameraException extends IOException {
|
public class CameraException extends IOException {
|
||||||
|
|
||||||
CameraException(String message) {
|
CameraException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ import org.briarproject.briar.R;
|
|||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BaseActivity;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactErrorFragment;
|
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.AddNearbyContactPermissionManager;
|
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactPermissionManager;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.util.RequestBluetoothDiscoverable;
|
import org.briarproject.briar.android.util.RequestBluetoothDiscoverable;
|
||||||
import org.briarproject.briar.api.socialbackup.BackupPayload;
|
import org.briarproject.briar.api.socialbackup.BackupPayload;
|
||||||
import org.briarproject.briar.api.socialbackup.MessageParser;
|
|
||||||
import org.briarproject.briar.api.socialbackup.ReturnShardPayload;
|
import org.briarproject.briar.api.socialbackup.ReturnShardPayload;
|
||||||
import org.briarproject.briar.api.socialbackup.Shard;
|
import org.briarproject.briar.api.socialbackup.Shard;
|
||||||
|
|
||||||
@@ -208,8 +206,8 @@ public class ReturnShardActivity extends BaseActivity
|
|||||||
private void showQrCodeFragment() {
|
private void showQrCodeFragment() {
|
||||||
// FIXME #824
|
// FIXME #824
|
||||||
FragmentManager fm = getSupportFragmentManager();
|
FragmentManager fm = getSupportFragmentManager();
|
||||||
if (fm.findFragmentByTag(AddNearbyContactFragment.TAG) == null) {
|
if (fm.findFragmentByTag(ReturnShardFragment.TAG) == null) {
|
||||||
BaseFragment f = AddNearbyContactFragment.newInstance();
|
BaseFragment f = ReturnShardFragment.newInstance();
|
||||||
fm.beginTransaction()
|
fm.beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
.addToBackStack(f.getUniqueTag())
|
.addToBackStack(f.getUniqueTag())
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
package org.briarproject.briar.android.socialbackup.recover;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
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.CameraException;
|
||||||
|
import org.briarproject.briar.android.contact.add.nearby.CameraView;
|
||||||
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.android.view.QrCodeView;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.UiThread;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
|
||||||
|
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||||
|
import static android.view.View.INVISIBLE;
|
||||||
|
import static android.view.View.VISIBLE;
|
||||||
|
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
import static android.widget.LinearLayout.HORIZONTAL;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class ReturnShardFragment extends BaseFragment
|
||||||
|
implements QrCodeView.FullscreenListener {
|
||||||
|
|
||||||
|
public static final String TAG = org.briarproject.briar.android.contact.add.nearby.AddNearbyContactFragment.class.getName();
|
||||||
|
|
||||||
|
private static final Logger LOG = Logger.getLogger(TAG);
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
private ReturnShardViewModel viewModel;
|
||||||
|
private CameraView cameraView;
|
||||||
|
private LinearLayout cameraOverlay;
|
||||||
|
private View statusView;
|
||||||
|
private QrCodeView qrCodeView;
|
||||||
|
private TextView status;
|
||||||
|
|
||||||
|
public static ReturnShardFragment newInstance() {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
ReturnShardFragment fragment = new ReturnShardFragment();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectFragment(ActivityComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
|
||||||
|
.get(ReturnShardViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_keyagreement_qr, container,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
cameraView = view.findViewById(R.id.camera_view);
|
||||||
|
cameraOverlay = view.findViewById(R.id.camera_overlay);
|
||||||
|
statusView = view.findViewById(R.id.status_container);
|
||||||
|
status = view.findViewById(R.id.connect_status);
|
||||||
|
qrCodeView = view.findViewById(R.id.qr_code_view);
|
||||||
|
qrCodeView.setFullscreenListener(this);
|
||||||
|
|
||||||
|
viewModel.getState().observe(getViewLifecycleOwner(),
|
||||||
|
this::onReturnShardStateChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
requireActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
|
||||||
|
cameraView.setPreviewConsumer(viewModel.getQrCodeDecoder());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
try {
|
||||||
|
cameraView.start();
|
||||||
|
} catch (CameraException e) {
|
||||||
|
logCameraExceptionAndFinish(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
try {
|
||||||
|
cameraView.stop();
|
||||||
|
} catch (CameraException e) {
|
||||||
|
logCameraExceptionAndFinish(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
requireActivity()
|
||||||
|
.setRequestedOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFullscreen(boolean fullscreen) {
|
||||||
|
LinearLayout.LayoutParams statusParams, qrCodeParams;
|
||||||
|
if (fullscreen) {
|
||||||
|
// Grow the QR code view to fill its parent
|
||||||
|
statusParams = new LinearLayout.LayoutParams(0, 0, 0f);
|
||||||
|
qrCodeParams = new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT, 1f);
|
||||||
|
} else {
|
||||||
|
// Shrink the QR code view to fill half its parent
|
||||||
|
if (cameraOverlay.getOrientation() == HORIZONTAL) {
|
||||||
|
statusParams = new LinearLayout.LayoutParams(0, MATCH_PARENT, 1f);
|
||||||
|
qrCodeParams = new LinearLayout.LayoutParams(0, MATCH_PARENT, 1f);
|
||||||
|
} else {
|
||||||
|
statusParams = new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1f);
|
||||||
|
qrCodeParams = new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
statusView.setLayoutParams(statusParams);
|
||||||
|
qrCodeView.setLayoutParams(qrCodeParams);
|
||||||
|
cameraOverlay.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
private void onReturnShardStateChanged(@Nullable ReturnShardState state) {
|
||||||
|
if (state instanceof ReturnShardState.KeyAgreementListening) {
|
||||||
|
Bitmap qrCode =
|
||||||
|
((ReturnShardState.KeyAgreementListening) state).qrCode;
|
||||||
|
qrCodeView.setQrCode(qrCode);
|
||||||
|
} else if (state instanceof ReturnShardState.QrCodeScanned) {
|
||||||
|
try {
|
||||||
|
cameraView.stop();
|
||||||
|
} catch (CameraException e) {
|
||||||
|
logCameraExceptionAndFinish(e);
|
||||||
|
}
|
||||||
|
cameraView.setVisibility(INVISIBLE);
|
||||||
|
statusView.setVisibility(VISIBLE);
|
||||||
|
status.setText(R.string.connecting_to_device);
|
||||||
|
} else if (state instanceof ReturnShardState.KeyAgreementWaiting) {
|
||||||
|
status.setText(R.string.waiting_for_contact_to_scan);
|
||||||
|
} else if (state instanceof ReturnShardState.KeyAgreementStarted) {
|
||||||
|
qrCodeView.setVisibility(INVISIBLE);
|
||||||
|
status.setText(R.string.authenticating_with_device);
|
||||||
|
} else if (state instanceof ReturnShardState.SocialBackupExchangeStarted) {
|
||||||
|
status.setText(R.string.exchanging_contact_details);
|
||||||
|
} else if (state instanceof ReturnShardState.Failed) {
|
||||||
|
// the activity will replace this fragment with an error fragment
|
||||||
|
statusView.setVisibility(INVISIBLE);
|
||||||
|
cameraView.setVisibility(INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueTag() {
|
||||||
|
return TAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
private void logCameraExceptionAndFinish(CameraException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
Toast.makeText(getActivity(), R.string.camera_error,
|
||||||
|
LENGTH_LONG).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finish() {
|
||||||
|
requireActivity().getSupportFragmentManager().popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -410,7 +410,7 @@ class ReturnShardViewModel extends AndroidViewModel
|
|||||||
@Override
|
@Override
|
||||||
@IoExecutor
|
@IoExecutor
|
||||||
public void onQrCodeDecoded(Result result) {
|
public void onQrCodeDecoded(Result result) {
|
||||||
LOG.info("Got result from decoder");
|
LOG.info("Got result from decoder"+gotLocalPayload+gotRemotePayload);
|
||||||
// Ignore results until the KeyAgreementTask is ready
|
// Ignore results until the KeyAgreementTask is ready
|
||||||
if (!gotLocalPayload || gotRemotePayload) return;
|
if (!gotLocalPayload || gotRemotePayload) return;
|
||||||
try {
|
try {
|
||||||
@@ -538,4 +538,8 @@ class ReturnShardViewModel extends AndroidViewModel
|
|||||||
public void setReturnShardPayload(ReturnShardPayload returnShardPayload) {
|
public void setReturnShardPayload(ReturnShardPayload returnShardPayload) {
|
||||||
this.returnShardPayload = returnShardPayload;
|
this.returnShardPayload = returnShardPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QrCodeDecoder getQrCodeDecoder() {
|
||||||
|
return qrCodeDecoder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user