mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 04:18:53 +01:00
Handle TorPlugin not being active during mailbox setup
This commit is contained in:
@@ -45,6 +45,7 @@ import org.briarproject.briar.android.hotspot.QrHotspotFragment;
|
|||||||
import org.briarproject.briar.android.logging.CachingLogHandler;
|
import org.briarproject.briar.android.logging.CachingLogHandler;
|
||||||
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
import org.briarproject.briar.android.login.SignInReminderReceiver;
|
||||||
import org.briarproject.briar.android.mailbox.MailboxScanFragment;
|
import org.briarproject.briar.android.mailbox.MailboxScanFragment;
|
||||||
|
import org.briarproject.briar.android.mailbox.OfflineFragment;
|
||||||
import org.briarproject.briar.android.removabledrive.ChooserFragment;
|
import org.briarproject.briar.android.removabledrive.ChooserFragment;
|
||||||
import org.briarproject.briar.android.removabledrive.ReceiveFragment;
|
import org.briarproject.briar.android.removabledrive.ReceiveFragment;
|
||||||
import org.briarproject.briar.android.removabledrive.SendFragment;
|
import org.briarproject.briar.android.removabledrive.SendFragment;
|
||||||
@@ -242,4 +243,6 @@ public interface AndroidComponent
|
|||||||
void inject(BluetoothIntroFragment bluetoothIntroFragment);
|
void inject(BluetoothIntroFragment bluetoothIntroFragment);
|
||||||
|
|
||||||
void inject(MailboxScanFragment mailboxScanFragment);
|
void inject(MailboxScanFragment mailboxScanFragment);
|
||||||
|
|
||||||
|
void inject(OfflineFragment offlineFragment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
onCodeScanned();
|
onCodeScanned();
|
||||||
} else if (state instanceof MailboxState.QrCodeWrong) {
|
} else if (state instanceof MailboxState.QrCodeWrong) {
|
||||||
onQrCodeWrong();
|
onQrCodeWrong();
|
||||||
|
} else if (state instanceof MailboxState.OfflineInSetup) {
|
||||||
|
onOffline();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -100,4 +102,9 @@ public class MailboxActivity extends BriarActivity {
|
|||||||
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
showFragment(getSupportFragmentManager(), f, ErrorFragment.TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onOffline() {
|
||||||
|
showFragment(getSupportFragmentManager(), new OfflineFragment(),
|
||||||
|
OfflineFragment.TAG);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.briarproject.briar.android.mailbox;
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
|
|
||||||
class MailboxState {
|
class MailboxState {
|
||||||
|
|
||||||
static class NotSetup extends MailboxState {
|
static class NotSetup extends MailboxState {
|
||||||
@@ -11,6 +13,14 @@ class MailboxState {
|
|||||||
static class QrCodeWrong extends MailboxState {
|
static class QrCodeWrong extends MailboxState {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class OfflineInSetup extends MailboxState {
|
||||||
|
final MailboxProperties mailboxProperties;
|
||||||
|
|
||||||
|
OfflineInSetup(MailboxProperties mailboxProperties) {
|
||||||
|
this.mailboxProperties = mailboxProperties;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO add other states
|
// TODO add other states
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
|||||||
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
import org.briarproject.bramble.api.mailbox.MailboxAuthToken;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
import org.briarproject.bramble.api.mailbox.MailboxProperties;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.plugin.Plugin;
|
||||||
|
import org.briarproject.bramble.api.plugin.PluginManager;
|
||||||
|
import org.briarproject.bramble.api.plugin.TorConstants;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
import org.briarproject.briar.android.mailbox.MailboxState.NotSetup;
|
||||||
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
import org.briarproject.briar.android.qrcode.QrCodeDecoder;
|
||||||
@@ -29,8 +32,10 @@ import androidx.annotation.UiThread;
|
|||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class MailboxViewModel extends DbViewModel
|
class MailboxViewModel extends DbViewModel
|
||||||
@@ -45,6 +50,7 @@ class MailboxViewModel extends DbViewModel
|
|||||||
|
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
private final QrCodeDecoder qrCodeDecoder;
|
private final QrCodeDecoder qrCodeDecoder;
|
||||||
|
private final PluginManager pluginManager;
|
||||||
|
|
||||||
private final MutableLiveData<MailboxState> state = new MutableLiveData<>();
|
private final MutableLiveData<MailboxState> state = new MutableLiveData<>();
|
||||||
|
|
||||||
@@ -56,9 +62,11 @@ class MailboxViewModel extends DbViewModel
|
|||||||
TransactionManager db,
|
TransactionManager db,
|
||||||
AndroidExecutor androidExecutor,
|
AndroidExecutor androidExecutor,
|
||||||
@IoExecutor Executor ioExecutor,
|
@IoExecutor Executor ioExecutor,
|
||||||
CryptoComponent crypto) {
|
CryptoComponent crypto,
|
||||||
|
PluginManager pluginManager) {
|
||||||
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
super(app, dbExecutor, lifecycleManager, db, androidExecutor);
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
|
this.pluginManager = pluginManager;
|
||||||
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this);
|
||||||
checkIfSetup();
|
checkIfSetup();
|
||||||
}
|
}
|
||||||
@@ -80,16 +88,17 @@ class MailboxViewModel extends DbViewModel
|
|||||||
@IoExecutor
|
@IoExecutor
|
||||||
public void onQrCodeDecoded(Result result) {
|
public void onQrCodeDecoded(Result result) {
|
||||||
LOG.info("Got result from decoder");
|
LOG.info("Got result from decoder");
|
||||||
|
MailboxProperties properties;
|
||||||
try {
|
try {
|
||||||
// TODO pass props to core (maybe even do payload parsing there)
|
properties = decodeQrCode(result.getText());
|
||||||
MailboxProperties properties = decodeQrCode(result.getText());
|
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
state.postValue(new MailboxState.QrCodeWrong());
|
state.postValue(new MailboxState.QrCodeWrong());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state.postValue(new MailboxState.SettingUp());
|
onMailboxPropertiesReceived(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move this into core #2168
|
||||||
private MailboxProperties decodeQrCode(String payload)
|
private MailboxProperties decodeQrCode(String payload)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
byte[] bytes = payload.getBytes(ISO_8859_1);
|
byte[] bytes = payload.getBytes(ISO_8859_1);
|
||||||
@@ -115,6 +124,28 @@ class MailboxViewModel extends DbViewModel
|
|||||||
return new MailboxProperties(onionAddress, setupToken, true);
|
return new MailboxProperties(onionAddress, setupToken, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onMailboxPropertiesReceived(MailboxProperties properties) {
|
||||||
|
if (isTorActive()) {
|
||||||
|
// TODO pass props to core #2168
|
||||||
|
state.postValue(new MailboxState.SettingUp());
|
||||||
|
} else {
|
||||||
|
state.postValue(new MailboxState.OfflineInSetup(properties));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO ideally also move this into core #2168
|
||||||
|
private boolean isTorActive() {
|
||||||
|
Plugin plugin = pluginManager.getPlugin(TorConstants.ID);
|
||||||
|
return plugin != null && plugin.getState() == ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
void tryAgainWhenOffline() {
|
||||||
|
MailboxState.OfflineInSetup offline =
|
||||||
|
(MailboxState.OfflineInSetup) requireNonNull(state.getValue());
|
||||||
|
onMailboxPropertiesReceived(offline.mailboxProperties);
|
||||||
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
QrCodeDecoder getQrCodeDecoder() {
|
QrCodeDecoder getQrCodeDecoder() {
|
||||||
return qrCodeDecoder;
|
return qrCodeDecoder;
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package org.briarproject.briar.android.mailbox;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
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 org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.navdrawer.TransportsActivity;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.activity.OnBackPressedCallback;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.widget.NestedScrollView;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import static android.view.View.FOCUS_DOWN;
|
||||||
|
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersNotNullByDefault
|
||||||
|
public class OfflineFragment extends Fragment {
|
||||||
|
|
||||||
|
public static final String TAG = OfflineFragment.class.getName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
private MailboxViewModel viewModel;
|
||||||
|
|
||||||
|
private NestedScrollView scrollView;
|
||||||
|
protected Button buttonView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
FragmentActivity activity = requireActivity();
|
||||||
|
getAndroidComponent(activity).inject(this);
|
||||||
|
viewModel = new ViewModelProvider(activity, viewModelFactory)
|
||||||
|
.get(MailboxViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View v = inflater
|
||||||
|
.inflate(R.layout.fragment_offline, container, false);
|
||||||
|
|
||||||
|
scrollView = (NestedScrollView) v;
|
||||||
|
TextView titleView = v.findViewById(R.id.titleView);
|
||||||
|
Button checkButton = v.findViewById(R.id.checkButton);
|
||||||
|
checkButton.setOnClickListener(view -> {
|
||||||
|
Intent i = new Intent(requireContext(), TransportsActivity.class);
|
||||||
|
startActivity(i);
|
||||||
|
});
|
||||||
|
buttonView = v.findViewById(R.id.button);
|
||||||
|
buttonView.setOnClickListener(view -> viewModel.tryAgainWhenOffline());
|
||||||
|
|
||||||
|
AppCompatActivity a = (AppCompatActivity) requireActivity();
|
||||||
|
a.setTitle(titleView.getText());
|
||||||
|
ActionBar actionBar = a.getSupportActionBar();
|
||||||
|
if (actionBar != null) {
|
||||||
|
actionBar.setDisplayHomeAsUpEnabled(false);
|
||||||
|
actionBar.setHomeButtonEnabled(false);
|
||||||
|
}
|
||||||
|
a.getOnBackPressedDispatcher().addCallback(
|
||||||
|
getViewLifecycleOwner(), new OnBackPressedCallback(true) {
|
||||||
|
@Override
|
||||||
|
public void handleOnBackPressed() {
|
||||||
|
onBackButtonPressed();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
// Scroll down in case the screen is small, so the button is visible
|
||||||
|
scrollView.post(() -> scrollView.fullScroll(FOCUS_DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onBackButtonPressed() {
|
||||||
|
requireActivity().supportFinishAfterTransition();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
81
briar-android/src/main/res/layout/fragment_offline.xml
Normal file
81
briar-android/src/main/res/layout/fragment_offline.xml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iconView"
|
||||||
|
android:layout_width="@dimen/hero_square"
|
||||||
|
android:layout_height="@dimen/hero_square"
|
||||||
|
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||||
|
android:layout_marginTop="@dimen/margin_xlarge"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/titleView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_bias="0.25"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
app:srcCompat="@drawable/transport_tor"
|
||||||
|
app:tint="@color/briar_red_500"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||||
|
android:layout_marginTop="@dimen/margin_xlarge"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/offline"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/textView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/iconView" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/textView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="@dimen/margin_xlarge"
|
||||||
|
android:layout_marginTop="@dimen/margin_xlarge"
|
||||||
|
android:layout_marginBottom="@dimen/margin_large"
|
||||||
|
android:text="@string/tor_offline_description"
|
||||||
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/checkButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/titleView" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/checkButton"
|
||||||
|
style="@style/BriarButtonFlat.Neutral"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_large"
|
||||||
|
android:text="@string/tor_offline_button_check"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/button"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/button"
|
||||||
|
style="@style/BriarButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_large"
|
||||||
|
android:text="@string/try_again_button"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.core.widget.NestedScrollView>
|
||||||
@@ -632,6 +632,9 @@
|
|||||||
<string name="mailbox_setup_connecting">Connecting…</string>
|
<string name="mailbox_setup_connecting">Connecting…</string>
|
||||||
<string name="mailbox_setup_qr_code_wrong_title">Wrong QR code</string>
|
<string name="mailbox_setup_qr_code_wrong_title">Wrong QR code</string>
|
||||||
<string name="mailbox_setup_qr_code_wrong_description">The scanned code is invalid. Please open the Briar Mailbox app and scan the QR code it presents.</string>
|
<string name="mailbox_setup_qr_code_wrong_description">The scanned code is invalid. Please open the Briar Mailbox app and scan the QR code it presents.</string>
|
||||||
|
<string name="tor_offline_title">Offline</string>
|
||||||
|
<string name="tor_offline_description">Ensure that this device is online and connections to the internet are allowed.\n\nAfterwards, wait for the globe icon in connection settings needs to turn green.</string>
|
||||||
|
<string name="tor_offline_button_check">Check connection settings</string>
|
||||||
|
|
||||||
<!-- Conversation Settings -->
|
<!-- Conversation Settings -->
|
||||||
<string name="disappearing_messages_title">Disappearing messages</string>
|
<string name="disappearing_messages_title">Disappearing messages</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user