From 4dbdd724adf3c39bd7242c6b7768f6853a30c15c Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 14 Aug 2020 17:52:00 +0100 Subject: [PATCH] DO NOT MERGE: Unofficial and very hacky account transfer feature. --- .../briar/android/account/AccountUtils.java | 93 +++++++++++++++++++ .../android/settings/SettingsFragment.java | 15 +++ briar-android/src/main/res/xml/settings.xml | 10 ++ 3 files changed, 118 insertions(+) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/account/AccountUtils.java diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/AccountUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/account/AccountUtils.java new file mode 100644 index 000000000..5c719b0d1 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/AccountUtils.java @@ -0,0 +1,93 @@ +package org.briarproject.briar.android.account; + +import android.content.Context; +import android.content.Intent; +import android.widget.Toast; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.logging.Logger; + +import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; +import static android.os.Environment.DIRECTORY_DOWNLOADS; +import static android.os.Environment.getExternalStoragePublicDirectory; +import static android.widget.Toast.LENGTH_LONG; +import static java.util.logging.Level.WARNING; +import static java.util.logging.Logger.getLogger; +import static org.briarproject.bramble.util.IoUtils.copyAndClose; +import static org.briarproject.bramble.util.LogUtils.logException; +import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY; +import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI; + +public class AccountUtils { + + private static final Logger LOG = getLogger(AccountUtils.class.getName()); + + private static final String[] BACKUP_DIRS = + {"app_db", "app_key", "shared_prefs"}; + + public static void exportAccount(Context ctx) { + try { + File dataDir = getDataDir(ctx); + File backupDir = getBackupDir(ctx); + for (String name : BACKUP_DIRS) { + copyRecursively(new File(dataDir, name), + new File(backupDir, name)); + } + Toast.makeText(ctx, "Account exported to " + + backupDir.getCanonicalPath(), LENGTH_LONG).show(); + } catch (IOException e) { + logException(LOG, WARNING, e); + Toast.makeText(ctx, "Export failed", LENGTH_LONG).show(); + } + } + + public static void importAccount(Context ctx) { + try { + File dataDir = getDataDir(ctx); + File backupDir = getBackupDir(ctx); + for (String name : BACKUP_DIRS) { + copyRecursively(new File(backupDir, name), + new File(dataDir, name)); + } + Toast.makeText(ctx, "Account imported from " + + backupDir.getCanonicalPath(), LENGTH_LONG).show(); + Intent intent = new Intent(ctx, ENTRY_ACTIVITY); + intent.setFlags(FLAG_ACTIVITY_CLEAR_TOP); + intent.setData(SIGN_OUT_URI); + ctx.startActivity(intent); + } catch (IOException e) { + logException(LOG, WARNING, e); + Toast.makeText(ctx, "Import failed", LENGTH_LONG).show(); + } + } + + private static File getDataDir(Context ctx) { + return new File(ctx.getApplicationInfo().dataDir); + } + + private static File getBackupDir(Context ctx) { + File downloads = getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS); + return new File(downloads, ctx.getPackageName()); + } + + private static void copyRecursively(File src, File dest) + throws IOException { + if (src.isDirectory()) { + if (!dest.isDirectory() && !dest.mkdirs()) throw new IOException(); + File[] children = src.listFiles(); + if (children == null) throw new IOException(); + for (File child : children) { + copyRecursively(child, new File(dest, child.getName())); + } + } else if (src.isFile()) { + InputStream in = new FileInputStream(src); + OutputStream out = new FileOutputStream(dest); + copyAndClose(in, out); + } + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java index c09f91190..2a06cf7dd 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java @@ -32,6 +32,7 @@ import org.briarproject.bramble.plugin.tor.CircumventionProvider; import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.R; import org.briarproject.briar.android.Localizer; +import org.briarproject.briar.android.account.AccountUtils; import org.briarproject.briar.android.util.UiUtils; import java.util.ArrayList; @@ -251,9 +252,23 @@ public class SettingsFragment extends PreferenceFragmentCompat throw new RuntimeException("Boom!"); } ); + findPreference("pref_key_export").setOnPreferenceClickListener( + preference -> { + AccountUtils.exportAccount(requireContext()); + return true; + } + ); + findPreference("pref_key_import").setOnPreferenceClickListener( + preference -> { + AccountUtils.importAccount(requireContext()); + return true; + } + ); } else { findPreference("pref_key_explode").setVisible(false); findPreference("pref_key_test_data").setVisible(false); + findPreference("pref_key_export").setVisible(false); + findPreference("pref_key_import").setVisible(false); PreferenceGroup testing = findPreference("pref_key_explode").getParent(); if (testing == null) throw new AssertionError(); diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index 21acdd98f..4a1d5d4d7 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -232,6 +232,16 @@ android:title="Crash" app:iconSpaceReserved="false"/> + + + +