Merge branch '1136-startup-failure-ux' into 'maintenance-0.16'

Backport: Improve UX for startup failures

See merge request akwizgran/briar!707
This commit is contained in:
akwizgran
2018-02-28 10:26:48 +00:00
8 changed files with 170 additions and 36 deletions

View File

@@ -21,7 +21,12 @@ public interface LifecycleManager {
* The result of calling {@link #startServices(String)}.
*/
enum StartResult {
ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS
ALREADY_RUNNING,
DB_ERROR,
DATA_TOO_OLD_ERROR,
DATA_TOO_NEW_ERROR,
SERVICE_ERROR,
SUCCESS
}
/**

View File

@@ -2,6 +2,8 @@ package org.briarproject.bramble.lifecycle;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.db.DataTooNewException;
import org.briarproject.bramble.api.db.DataTooOldException;
import org.briarproject.bramble.api.db.DatabaseComponent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.db.Transaction;
@@ -30,6 +32,8 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DATA_TOO_NEW_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DATA_TOO_OLD_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
@@ -159,6 +163,12 @@ class LifecycleManagerImpl implements LifecycleManager {
}
startupLatch.countDown();
return SUCCESS;
} catch (DataTooOldException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DATA_TOO_OLD_ERROR;
} catch (DataTooNewException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DATA_TOO_NEW_ERROR;
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return DB_ERROR;

View File

@@ -3,29 +3,31 @@ package org.briarproject.briar.android;
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BaseActivity;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.briar.android.fragment.ErrorFragment;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult;
import static org.briarproject.briar.android.BriarService.EXTRA_NOTIFICATION_ID;
import static org.briarproject.briar.android.BriarService.EXTRA_START_RESULT;
public class StartupFailureActivity extends BaseActivity {
public class StartupFailureActivity extends BaseActivity implements
BaseFragmentListener {
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_startup_failure);
setContentView(R.layout.activity_fragment_container);
handleIntent(getIntent());
}
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
private void handleIntent(Intent i) {
@@ -41,12 +43,31 @@ public class StartupFailureActivity extends BaseActivity {
}
// show proper error message
TextView view = findViewById(R.id.errorView);
if (result.equals(StartResult.DB_ERROR)) {
view.setText(getText(R.string.startup_failed_db_error));
} else if (result.equals(StartResult.SERVICE_ERROR)) {
view.setText(getText(R.string.startup_failed_service_error));
String errorMsg;
switch (result) {
case DATA_TOO_OLD_ERROR:
errorMsg = getString(R.string.startup_failed_db_error);
break;
case DATA_TOO_NEW_ERROR:
errorMsg =
getString(R.string.startup_failed_data_too_new_error);
break;
case DB_ERROR:
errorMsg =
getString(R.string.startup_failed_data_too_old_error);
break;
case SERVICE_ERROR:
errorMsg = getString(R.string.startup_failed_service_error);
break;
default:
throw new IllegalArgumentException();
}
showInitialFragment(ErrorFragment.newInstance(errorMsg));
}
@Override
public void runOnDbThread(Runnable runnable) {
throw new AssertionError("Deprecated and should not be used");
}
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.android.activity;
import android.app.Activity;
import org.briarproject.briar.android.AndroidComponent;
import org.briarproject.briar.android.StartupFailureActivity;
import org.briarproject.briar.android.blog.BlogActivity;
import org.briarproject.briar.android.blog.BlogFragment;
import org.briarproject.briar.android.blog.BlogModule;
@@ -151,6 +152,8 @@ public interface ActivityComponent {
void inject(RssFeedManageActivity activity);
void inject(StartupFailureActivity activity);
// Fragments
void inject(AuthorNameFragment fragment);

View File

@@ -0,0 +1,65 @@
package org.briarproject.briar.android.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
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.activity.ActivityComponent;
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ErrorFragment extends BaseFragment {
private static final String TAG = ErrorFragment.class.getSimpleName();
private static final String ERROR_MSG = "errorMessage";
public static ErrorFragment newInstance(String message) {
ErrorFragment f = new ErrorFragment();
Bundle args = new Bundle();
args.putString(ERROR_MSG, message);
f.setArguments(args);
return f;
}
private String errorMessage;
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args == null) throw new AssertionError();
errorMessage = args.getString(ERROR_MSG);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View v = inflater
.inflate(R.layout.fragment_error, container, false);
TextView msg = v.findViewById(R.id.errorMessage);
msg.setText(errorMessage);
return v;
}
@Override
public void injectFragment(ActivityComponent component) {
// not necessary
}
}

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/margin_activity_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/BriarTextTitle"
android:text="@string/startup_failed_notification_title"
android:layout_gravity="center_horizontal"
android:layout_marginTop="7dp"
android:layout_marginBottom="7dp"/>
<TextView
android:id="@+id/errorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/startup_failed_notification_text"/>
</LinearLayout>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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">
<ImageView
android:id="@+id/errorIcon"
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:src="@drawable/alerts_and_states_error"
android:tint="?colorControlNormal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription"/>
<TextView
android:id="@+id/errorTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/sorry"
android:textSize="@dimen/text_size_xlarge"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/errorIcon"/>
<TextView
android:id="@+id/errorMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:textSize="@dimen/text_size_medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/errorTitle"
tools:text="@string/startup_failed_db_error"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -34,9 +34,11 @@
<string name="dialog_title_lost_password">Lost Password</string>
<string name="dialog_message_lost_password">Your Briar account is stored encrypted on your device, not in the cloud, so we can\'t reset your password. Would you like to delete your account and start again?\n\nCaution: Your identities, contacts and messages will be permanently lost.</string>
<string name="startup_failed_notification_title">Briar could not start</string>
<string name="startup_failed_notification_text">You may need to reinstall Briar.</string>
<string name="startup_failed_notification_text">Tap for more information.</string>
<string name="startup_failed_activity_title">Briar Startup Failure</string>
<string name="startup_failed_db_error">For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account.</string>
<string name="startup_failed_db_error">For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account by choosing \'I have forgotten my password\' at the password prompt.</string>
<string name="startup_failed_data_too_old_error">Your account was created with an old version of this app and cannot be opened with this version. You must either reinstall the old version or delete your old account by choosing \'I have forgotten my password\' at the password prompt.</string>
<string name="startup_failed_data_too_new_error">This version of the app is too old. Please upgrade to the latest version and try again.</string>
<string name="startup_failed_service_error">Briar was unable to start a required plugin. Reinstalling Briar usually solves this problem. However, please note that you will then lose your account and all data associated with it since Briar is not using central servers to store your data on.</string>
<plurals name="expiry_warning">
<item quantity="one">This is a beta version of Briar. Your account will expire in %d day and cannot be renewed.</item>
@@ -101,6 +103,7 @@
<string name="show_onboarding">Show Help Dialog</string>
<string name="fix">Fix</string>
<string name="help">Help</string>
<string name="sorry">Sorry</string>
<!-- Contacts and Private Conversations-->
<string name="no_contacts">It seems that you are new here and have no contacts yet.\n\nTap the + icon at the top and follow the instructions to add some friends to your list.\n\nPlease remember: You can only add new contacts face-to-face to prevent anyone from impersonating you or reading your messages in the future.</string>