add import-backup

This commit is contained in:
B. Petersen
2018-08-31 18:38:35 +02:00
parent cd4644e6e3
commit de24ee3892
4 changed files with 139 additions and 13 deletions
+5 -1
View File
@@ -1368,7 +1368,6 @@
<string name="prompt_passphrase_activity__tap_to_unlock">TAP TO UNLOCK</string>
<string name="RegistrationLockDialog_reminder">Reminder:</string>
<string name="recipient_preferences__about">About</string>
<!-- EOF -->
<string name="WelcomeActivity_intro1_headline">Delta Chat</string>
<string name="WelcomeActivity_intro1_message">The messenger with the <b>broadest audience</b> in the world. <b>Free</b> and <b>independent</b>.</string>
@@ -1406,11 +1405,16 @@
<string name="RegistrationActivity_dialog_permission_text">Delta Chat needs access to your contacts and media in order to connect with friends and send files</string>
<string name="RegistrationActivity_error_required_fields">Please enter a valid email address and a password</string>
<string name="import_backup_title">Import backup</string>
<string name="import_backup_ask">Backup found at \"%1$s\".\n\nDo you want to import and use all data and settings from it?</string>
<string name="import_backup_no_backup_found">No backups found.\n\nCopy the backup to \"%1$s\" and try again. Alternatively, press \"Start messaging\" to go with the normal setup process.</string>
<!-- Generic and reusable strings -->
<string name="email_address">Email address</string>
<string name="password">Password</string>
<string name="advanced">Advanced</string>
<string name="icon">icon</string>
<string name="loading">Loading …</string>
<string name="one_moment">One moment …</string>
</resources>
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -22,6 +23,7 @@ import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEventCenter;
import com.dd.CircularProgressButton;
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.util.Dialogs;
@@ -222,6 +224,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
// calling configure() results in
// receiving multiple DC_EVENT_CONFIGURE_PROGRESS events
DcHelper.getContext(this).captureNextError();
DcHelper.getContext(this).configure();
}
@@ -240,14 +243,24 @@ public class RegistrationActivity extends BaseActionBarActivity implements DcEve
@Override
public void handleEvent(int eventId, Object data1, Object data2) {
if (eventId==DcContext.DC_EVENT_CONFIGURE_PROGRESS) {
ApplicationDcContext dcContext = DcHelper.getContext(this);
long progress = (Long)data1;
if (progress==0/*error/aborted*/) {
dcContext.endCaptureNextError();
progressDialog.dismiss();
if (dcContext.hasCapturedError()) {
new AlertDialog.Builder(this)
.setMessage(dcContext.getCapturedError())
.setPositiveButton(android.R.string.ok, null)
.show();
}
}
else if (progress<1000/*progress in permille*/) {
progressDialog.setMessage("Loading ... " + progress);
int percent = (int)progress / 10;
progressDialog.setMessage(getResources().getString(R.string.one_moment)+String.format(" %d%%", percent));
}
else if (progress==1000/*done*/) {
dcContext.endCaptureNextError();
progressDialog.dismiss();
Intent conversationList = new Intent(getApplicationContext(), ConversationListActivity.class);
startActivity(conversationList);
@@ -2,7 +2,10 @@ package org.thoughtcrime.securesms;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
@@ -19,9 +22,12 @@ import android.widget.TextView;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEventCenter;
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
import org.thoughtcrime.securesms.connect.DcHelper;
import org.thoughtcrime.securesms.permissions.Permissions;
import java.io.File;
/**
* The welcome activity. Provides the user with useful information about the app.
* It also allows the triggering of the backup import process.
@@ -85,7 +91,10 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
setContentView(R.layout.welcome_activity);
initializeResources();
DcHelper.getContext(this).eventCenter.addObserver(this, DcContext.DC_EVENT_CONFIGURE_PROGRESS);
ApplicationDcContext dcContext = DcHelper.getContext(this);
dcContext.eventCenter.addObserver(this, DcContext.DC_EVENT_CONFIGURE_PROGRESS);
dcContext.eventCenter.addObserver(this, DcContext.DC_EVENT_IMEX_PROGRESS);
}
@Override
@@ -108,8 +117,8 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
View backupText = findViewById(R.id.backup_text);
View backupImage = findViewById(R.id.backup_icon);
skipButton.setOnClickListener((view) -> startRegistrationActivity());
backupText.setOnClickListener((view) -> initializePermissions());
backupImage.setOnClickListener((view) -> initializePermissions());
backupText.setOnClickListener((view) -> startImportBackup());
backupImage.setOnClickListener((view) -> startImportBackup());
}
private void startRegistrationActivity() {
@@ -119,20 +128,87 @@ public class WelcomeActivity extends BaseActionBarActivity implements DcEventCen
}
@SuppressLint("InlinedApi")
private void initializePermissions() {
private void startImportBackup() {
Permissions.with(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
.ifNecessary()
.withRationaleDialog("Delta Chat needs access to your files in order start the backup import",
R.drawable.ic_folder_white_48dp)
.onAllGranted(() -> {
//JavaBindings.loadBackup(); TODO load backup value via bindings
ApplicationDcContext dcContext = DcHelper.getContext(this);
File imexDir = dcContext.getImexDir();
final String backupFile = dcContext.imexHasBackup(imexDir.getAbsolutePath());
if (backupFile != null) {
new AlertDialog.Builder(this)
.setTitle(R.string.import_backup_title)
.setMessage(String.format(getResources().getString(R.string.import_backup_ask), backupFile))
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
startImport(backupFile);
})
.show();
}
else {
new AlertDialog.Builder(this)
.setTitle(R.string.import_backup_title)
.setMessage(String.format(getResources().getString(R.string.import_backup_no_backup_found), imexDir.getAbsolutePath()))
.setPositiveButton(android.R.string.ok, null)
.show();
}
})
.execute();
}
private ProgressDialog progressDialog = null;
private void startImport(final String backupFile)
{
ApplicationDcContext dcContext = DcHelper.getContext(this);
if( progressDialog!=null ) {
progressDialog.dismiss();
progressDialog = null;
}
progressDialog = new ProgressDialog(this);
progressDialog.setMessage(getResources().getString(R.string.one_moment));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(android.R.string.cancel), (dialog, which) -> {
dcContext.stopOngoingProcess();
});
progressDialog.show();
dcContext.captureNextError();
dcContext.imex(DcContext.DC_IMEX_IMPORT_BACKUP, backupFile);
}
public void handleEvent(int eventId, Object data1, Object data2) {
if (eventId== DcContext.DC_EVENT_CONFIGURE_PROGRESS) {
if (eventId== DcContext.DC_EVENT_IMEX_PROGRESS) {
ApplicationDcContext dcContext = DcHelper.getContext(this);
long progress = (Long)data1;
if (progress==0/*error/aborted*/) {
dcContext.endCaptureNextError();
progressDialog.dismiss();
if (dcContext.hasCapturedError()) {
new AlertDialog.Builder(this)
.setMessage(dcContext.getCapturedError())
.setPositiveButton(android.R.string.ok, null)
.show();
}
}
else if (progress<1000/*progress in permille*/) {
int percent = (int)progress / 10;
progressDialog.setMessage(getResources().getString(R.string.one_moment)+String.format(" %d%%", percent));
}
else if (progress==1000/*done*/) {
dcContext.endCaptureNextError();
progressDialog.dismiss();
Intent conversationList = new Intent(getApplicationContext(), ConversationListActivity.class);
startActivity(conversationList);
finish();
}
}
else if (eventId== DcContext.DC_EVENT_CONFIGURE_PROGRESS) {
long progress = (Long)data1;
if (progress==1000/*done*/) {
finish(); // remove ourself from the activity stack (finishAffinity is available in API 16, we're targeting API 14)
@@ -17,6 +17,7 @@
package org.thoughtcrime.securesms.connect;
import android.content.Context;
import android.os.Environment;
import android.os.PowerManager;
import android.util.Log;
import android.widget.Toast;
@@ -67,6 +68,15 @@ public class ApplicationDcContext extends DcContext {
startThreads();
}
public File getImexDir()
{
// DIRECTORY_DOCUMENTS is only available since KitKat;
// as we also support Ice Cream Sandwich and Jellybean (2017: 11% in total), this is no option.
// Moreover, DIRECTORY_DOWNLOADS seems to be easier accessible by the user,
// eg. "Download Managers" are nearly always installed.
// CAVE: do not use DownloadManager to add the file as it is deleted on uninstall then ...
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
}
/***********************************************************************************************
* Working Threads
@@ -182,10 +192,34 @@ public class ApplicationDcContext extends DcContext {
public DcEventCenter eventCenter = new DcEventCenter();
public final Object lastErrorLock = new Object();
public int lastErrorCode = 0;
public String lastErrorString = "";
public boolean showNextErrorAsToast = true;
private final Object lastErrorLock = new Object();
private String lastErrorString = "";
private boolean showNextErrorAsToast = true;
public void captureNextError() {
synchronized (lastErrorLock) {
showNextErrorAsToast = false;
lastErrorString = "";
}
}
public boolean hasCapturedError() {
synchronized (lastErrorLock) {
return !lastErrorString.isEmpty();
}
}
public String getCapturedError() {
synchronized (lastErrorLock) {
return lastErrorString;
}
}
public void endCaptureNextError() {
synchronized (lastErrorLock) {
showNextErrorAsToast = true;
}
}
@Override public long handleEvent(final int event, long data1, long data2) {
switch(event) {
@@ -200,7 +234,6 @@ public class ApplicationDcContext extends DcContext {
case DC_EVENT_ERROR:
Log.e("DeltaChat", dataToString(data2));
synchronized (lastErrorLock) {
lastErrorCode = (int)data1;
lastErrorString = dataToString(data2);
}
Util.runOnMain(new Runnable() {