mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 17:27:45 +00:00
Backup file database table.
New backup util class.
This commit is contained in:
parent
8b98f85470
commit
5a5702302f
@ -57,7 +57,7 @@ import org.thoughtcrime.securesms.permissions.Permissions;
|
|||||||
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
import org.thoughtcrime.securesms.push.AccountManagerFactory;
|
||||||
import org.thoughtcrime.securesms.registration.CaptchaActivity;
|
import org.thoughtcrime.securesms.registration.CaptchaActivity;
|
||||||
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener;
|
||||||
import org.thoughtcrime.securesms.util.BackupUtil;
|
import org.thoughtcrime.securesms.util.BackupUtilOld;
|
||||||
import org.thoughtcrime.securesms.util.DateUtils;
|
import org.thoughtcrime.securesms.util.DateUtils;
|
||||||
import org.thoughtcrime.securesms.util.Dialogs;
|
import org.thoughtcrime.securesms.util.Dialogs;
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
@ -76,7 +76,6 @@ import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
|
|||||||
import org.whispersystems.signalservice.internal.push.LockedException;
|
import org.whispersystems.signalservice.internal.push.LockedException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -275,11 +274,11 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
|
|||||||
|
|
||||||
if (getIntent().getBooleanExtra(RE_REGISTRATION_EXTRA, false)) return;
|
if (getIntent().getBooleanExtra(RE_REGISTRATION_EXTRA, false)) return;
|
||||||
|
|
||||||
new AsyncTask<Void, Void, BackupUtil.BackupInfo>() {
|
new AsyncTask<Void, Void, BackupUtilOld.BackupInfo>() {
|
||||||
@Override
|
@Override
|
||||||
protected @Nullable BackupUtil.BackupInfo doInBackground(Void... voids) {
|
protected @Nullable BackupUtilOld.BackupInfo doInBackground(Void... voids) {
|
||||||
try {
|
try {
|
||||||
return BackupUtil.getLatestBackup(RegistrationActivity.this);
|
return BackupUtilOld.getLatestBackup(RegistrationActivity.this);
|
||||||
} catch (NoExternalStorageException e) {
|
} catch (NoExternalStorageException e) {
|
||||||
Log.w(TAG, e);
|
Log.w(TAG, e);
|
||||||
return null;
|
return null;
|
||||||
@ -287,7 +286,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(@Nullable BackupUtil.BackupInfo backup) {
|
protected void onPostExecute(@Nullable BackupUtilOld.BackupInfo backup) {
|
||||||
if (backup != null) displayRestoreView(backup);
|
if (backup != null) displayRestoreView(backup);
|
||||||
}
|
}
|
||||||
}.execute();
|
}.execute();
|
||||||
@ -304,7 +303,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
private void handleRestore(BackupUtil.BackupInfo backup) {
|
private void handleRestore(BackupUtilOld.BackupInfo backup) {
|
||||||
View view = LayoutInflater.from(this).inflate(R.layout.enter_backup_passphrase_dialog, null);
|
View view = LayoutInflater.from(this).inflate(R.layout.enter_backup_passphrase_dialog, null);
|
||||||
EditText prompt = view.findViewById(R.id.restore_passphrase_input);
|
EditText prompt = view.findViewById(R.id.restore_passphrase_input);
|
||||||
|
|
||||||
@ -661,7 +660,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayRestoreView(@NonNull BackupUtil.BackupInfo backup) {
|
private void displayRestoreView(@NonNull BackupUtilOld.BackupInfo backup) {
|
||||||
title.animate().translationX(title.getWidth()).setDuration(SCENE_TRANSITION_DURATION).setListener(new AnimationCompleteListener() {
|
title.animate().translationX(title.getWidth()).setDuration(SCENE_TRANSITION_DURATION).setListener(new AnimationCompleteListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationEnd(Animator animation) {
|
public void onAnimationEnd(Animator animation) {
|
||||||
|
@ -15,6 +15,7 @@ import network.loki.messenger.R;
|
|||||||
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
|
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
|
||||||
import org.thoughtcrime.securesms.service.LocalBackupListener;
|
import org.thoughtcrime.securesms.service.LocalBackupListener;
|
||||||
import org.thoughtcrime.securesms.util.BackupUtil;
|
import org.thoughtcrime.securesms.util.BackupUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.BackupUtilOld;
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ public class BackupDialog {
|
|||||||
.setPositiveButton(R.string.BackupDialog_delete_backups_statement, (dialog, which) -> {
|
.setPositiveButton(R.string.BackupDialog_delete_backups_statement, (dialog, which) -> {
|
||||||
BackupPassphrase.set(context, null);
|
BackupPassphrase.set(context, null);
|
||||||
TextSecurePreferences.setBackupEnabled(context, false);
|
TextSecurePreferences.setBackupEnabled(context, false);
|
||||||
BackupUtil.deleteAllBackups(context);
|
BackupUtilOld.deleteAllBackups(context);
|
||||||
preference.setChecked(false);
|
preference.setChecked(false);
|
||||||
})
|
})
|
||||||
.create()
|
.create()
|
||||||
|
@ -74,6 +74,7 @@ public class DatabaseFactory {
|
|||||||
private final LokiMessageDatabase lokiMessageDatabase;
|
private final LokiMessageDatabase lokiMessageDatabase;
|
||||||
private final LokiThreadDatabase lokiThreadDatabase;
|
private final LokiThreadDatabase lokiThreadDatabase;
|
||||||
private final LokiUserDatabase lokiUserDatabase;
|
private final LokiUserDatabase lokiUserDatabase;
|
||||||
|
private final LokiBackupFilesDatabase lokiBackupFilesDatabase;
|
||||||
private final SharedSenderKeysDatabase sskDatabase;
|
private final SharedSenderKeysDatabase sskDatabase;
|
||||||
|
|
||||||
public static DatabaseFactory getInstance(Context context) {
|
public static DatabaseFactory getInstance(Context context) {
|
||||||
@ -190,6 +191,10 @@ public class DatabaseFactory {
|
|||||||
return getInstance(context).lokiUserDatabase;
|
return getInstance(context).lokiUserDatabase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static LokiBackupFilesDatabase getLokiBackupFilesDatabase(Context context) {
|
||||||
|
return getInstance(context).lokiBackupFilesDatabase;
|
||||||
|
}
|
||||||
|
|
||||||
public static SharedSenderKeysDatabase getSSKDatabase(Context context) {
|
public static SharedSenderKeysDatabase getSSKDatabase(Context context) {
|
||||||
return getInstance(context).sskDatabase;
|
return getInstance(context).sskDatabase;
|
||||||
}
|
}
|
||||||
@ -232,6 +237,7 @@ public class DatabaseFactory {
|
|||||||
this.lokiMessageDatabase = new LokiMessageDatabase(context, databaseHelper);
|
this.lokiMessageDatabase = new LokiMessageDatabase(context, databaseHelper);
|
||||||
this.lokiThreadDatabase = new LokiThreadDatabase(context, databaseHelper);
|
this.lokiThreadDatabase = new LokiThreadDatabase(context, databaseHelper);
|
||||||
this.lokiUserDatabase = new LokiUserDatabase(context, databaseHelper);
|
this.lokiUserDatabase = new LokiUserDatabase(context, databaseHelper);
|
||||||
|
this.lokiBackupFilesDatabase = new LokiBackupFilesDatabase(context, databaseHelper);
|
||||||
this.sskDatabase = new SharedSenderKeysDatabase(context, databaseHelper);
|
this.sskDatabase = new SharedSenderKeysDatabase(context, databaseHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,105 @@
|
|||||||
|
package org.thoughtcrime.securesms.database
|
||||||
|
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.database.Cursor
|
||||||
|
import android.net.Uri
|
||||||
|
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||||
|
import org.thoughtcrime.securesms.database.model.BackupFileRecord
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of the backup files saved by the app.
|
||||||
|
* Uses [BackupFileRecord] as an entry data projection.
|
||||||
|
*/
|
||||||
|
class LokiBackupFilesDatabase(context: Context?, databaseHelper: SQLCipherOpenHelper?)
|
||||||
|
: Database(context, databaseHelper) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TABLE_NAME = "backup_files"
|
||||||
|
private const val COLUMN_ID = "_id"
|
||||||
|
private const val COLUMN_URI = "uri"
|
||||||
|
private const val COLUMN_FILE_SIZE = "file_size"
|
||||||
|
private const val COLUMN_TIMESTAMP = "timestamp"
|
||||||
|
|
||||||
|
private val allColumns = arrayOf(COLUMN_ID, COLUMN_URI, COLUMN_FILE_SIZE, COLUMN_TIMESTAMP)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val createTableCommand = """
|
||||||
|
CREATE TABLE $TABLE_NAME (
|
||||||
|
$COLUMN_ID INTEGER PRIMARY KEY,
|
||||||
|
$COLUMN_URI TEXT NOT NULL,
|
||||||
|
$COLUMN_FILE_SIZE INTEGER NOT NULL,
|
||||||
|
$COLUMN_TIMESTAMP INTEGER NOT NULL
|
||||||
|
);
|
||||||
|
""".trimIndent()
|
||||||
|
|
||||||
|
private fun mapCursorToRecord(cursor: Cursor): BackupFileRecord {
|
||||||
|
val id = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_ID))
|
||||||
|
val uriRaw = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_URI))
|
||||||
|
val fileSize = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_FILE_SIZE))
|
||||||
|
val timestampRaw = cursor.getLong(cursor.getColumnIndexOrThrow(COLUMN_TIMESTAMP))
|
||||||
|
return BackupFileRecord(id, Uri.parse(uriRaw), fileSize, Date(timestampRaw))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun mapRecordToValues(record: BackupFileRecord): ContentValues {
|
||||||
|
val contentValues = ContentValues()
|
||||||
|
if (record.id >= 0) { contentValues.put(COLUMN_ID, record.id) }
|
||||||
|
contentValues.put(COLUMN_URI, record.uri.toString())
|
||||||
|
contentValues.put(COLUMN_FILE_SIZE, record.fileSize)
|
||||||
|
contentValues.put(COLUMN_TIMESTAMP, record.timestamp.time)
|
||||||
|
return contentValues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBackupFiles(): List<BackupFileRecord> {
|
||||||
|
databaseHelper.readableDatabase.query(TABLE_NAME, allColumns, null, null, null, null, null).use {
|
||||||
|
val records = ArrayList<BackupFileRecord>()
|
||||||
|
while (it != null && it.moveToFirst()) {
|
||||||
|
val record = mapCursorToRecord(it)
|
||||||
|
records.add(record)
|
||||||
|
}
|
||||||
|
return records
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun insertBackupFile(record: BackupFileRecord): Long {
|
||||||
|
val contentValues = mapRecordToValues(record)
|
||||||
|
return databaseHelper.writableDatabase.insertOrThrow(TABLE_NAME, null, contentValues)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastBackupFileTime(): Date? {
|
||||||
|
// SELECT $COLUMN_TIMESTAMP FROM $TABLE_NAME ORDER BY $COLUMN_TIMESTAMP DESC LIMIT 1
|
||||||
|
databaseHelper.readableDatabase.query(
|
||||||
|
TABLE_NAME,
|
||||||
|
arrayOf(COLUMN_TIMESTAMP),
|
||||||
|
null, null, null, null,
|
||||||
|
"$COLUMN_TIMESTAMP DESC",
|
||||||
|
"1"
|
||||||
|
).use {
|
||||||
|
if (it !== null && it.moveToFirst()) {
|
||||||
|
return Date(it.getLong(0))
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLastBackupFile(): BackupFileRecord? {
|
||||||
|
// SELECT * FROM $TABLE_NAME ORDER BY $COLUMN_TIMESTAMP DESC LIMIT 1
|
||||||
|
databaseHelper.readableDatabase.query(
|
||||||
|
TABLE_NAME,
|
||||||
|
allColumns,
|
||||||
|
null, null, null, null,
|
||||||
|
"$COLUMN_TIMESTAMP DESC",
|
||||||
|
"1"
|
||||||
|
).use {
|
||||||
|
if (it != null && it.moveToFirst()) {
|
||||||
|
return mapCursorToRecord(it)
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.database.GroupDatabase;
|
|||||||
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
|
||||||
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
import org.thoughtcrime.securesms.database.IdentityDatabase;
|
||||||
import org.thoughtcrime.securesms.database.JobDatabase;
|
import org.thoughtcrime.securesms.database.JobDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.LokiBackupFilesDatabase;
|
||||||
import org.thoughtcrime.securesms.database.MmsDatabase;
|
import org.thoughtcrime.securesms.database.MmsDatabase;
|
||||||
import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase;
|
import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase;
|
||||||
import org.thoughtcrime.securesms.database.PushDatabase;
|
import org.thoughtcrime.securesms.database.PushDatabase;
|
||||||
@ -89,8 +90,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
private static final int lokiV11 = 32;
|
private static final int lokiV11 = 32;
|
||||||
private static final int lokiV12 = 33;
|
private static final int lokiV12 = 33;
|
||||||
private static final int lokiV13 = 34;
|
private static final int lokiV13 = 34;
|
||||||
|
private static final int lokiV14_BACKUP_FILES = 35;
|
||||||
|
|
||||||
private static final int DATABASE_VERSION = lokiV13; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
|
private static final int DATABASE_VERSION = lokiV14_BACKUP_FILES; // Loki - onUpgrade(...) must be updated to use Loki version numbers if Session makes any database changes
|
||||||
private static final String DATABASE_NAME = "signal.db";
|
private static final String DATABASE_NAME = "signal.db";
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
@ -161,6 +163,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
|
db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
|
||||||
db.execSQL(LokiUserDatabase.getCreateDisplayNameTableCommand());
|
db.execSQL(LokiUserDatabase.getCreateDisplayNameTableCommand());
|
||||||
db.execSQL(LokiUserDatabase.getCreateServerDisplayNameTableCommand());
|
db.execSQL(LokiUserDatabase.getCreateServerDisplayNameTableCommand());
|
||||||
|
db.execSQL(LokiBackupFilesDatabase.getCreateTableCommand());
|
||||||
db.execSQL(SharedSenderKeysDatabase.getCreateClosedGroupRatchetTableCommand());
|
db.execSQL(SharedSenderKeysDatabase.getCreateClosedGroupRatchetTableCommand());
|
||||||
db.execSQL(SharedSenderKeysDatabase.getCreateClosedGroupPrivateKeyTableCommand());
|
db.execSQL(SharedSenderKeysDatabase.getCreateClosedGroupPrivateKeyTableCommand());
|
||||||
|
|
||||||
@ -619,6 +622,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||||||
db.execSQL(LokiAPIDatabase.getCreateReceivedMessageHashValuesTable3Command());
|
db.execSQL(LokiAPIDatabase.getCreateReceivedMessageHashValuesTable3Command());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (oldVersion < lokiV14_BACKUP_FILES) {
|
||||||
|
db.execSQL(LokiBackupFilesDatabase.getCreateTableCommand());
|
||||||
|
}
|
||||||
|
|
||||||
db.setTransactionSuccessful();
|
db.setTransactionSuccessful();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction();
|
db.endTransaction();
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
package org.thoughtcrime.securesms.database.model
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a record for a backup file in the [org.thoughtcrime.securesms.database.LokiBackupFilesDatabase].
|
||||||
|
*/
|
||||||
|
data class BackupFileRecord(val id: Long, val uri: Uri, val fileSize: Long, val timestamp: Date) {
|
||||||
|
|
||||||
|
constructor(uri: Uri, fileSize: Long, timestamp: Date): this(-1, uri, fileSize, timestamp)
|
||||||
|
}
|
@ -15,7 +15,7 @@ import org.thoughtcrime.securesms.logging.Log;
|
|||||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||||
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
import org.thoughtcrime.securesms.service.GenericForegroundService;
|
||||||
import org.thoughtcrime.securesms.util.BackupUtil;
|
import org.thoughtcrime.securesms.util.BackupUtilOld;
|
||||||
import org.thoughtcrime.securesms.util.ExternalStorageUtil;
|
import org.thoughtcrime.securesms.util.ExternalStorageUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -98,7 +98,7 @@ public class LocalBackupJob extends BaseJob {
|
|||||||
throw new IOException("Renaming temporary backup file failed!");
|
throw new IOException("Renaming temporary backup file failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
BackupUtil.deleteOldBackups(context);
|
BackupUtilOld.deleteOldBackups(context);
|
||||||
} finally {
|
} finally {
|
||||||
GenericForegroundService.stopForegroundTask(context);
|
GenericForegroundService.stopForegroundTask(context);
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,13 @@ import android.annotation.SuppressLint;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.preference.EditTextPreference;
|
import androidx.preference.EditTextPreference;
|
||||||
import androidx.preference.Preference;
|
import androidx.preference.Preference;
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
import org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.Subscribe;
|
||||||
@ -106,8 +107,9 @@ public class ChatsPreferenceFragment extends ListSummaryPreferenceFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setBackupSummary() {
|
private void setBackupSummary() {
|
||||||
findPreference(TextSecurePreferences.BACKUP_NOW)
|
findPreference(TextSecurePreferences.BACKUP_NOW).setSummary(
|
||||||
.setSummary(String.format(getString(R.string.ChatsPreferenceFragment_last_backup_s), BackupUtil.getLastBackupTime(getContext(), Locale.US)));
|
String.format(getString(R.string.ChatsPreferenceFragment_last_backup_s),
|
||||||
|
BackupUtil.getLastBackupTimeString(getContext(), Locale.getDefault())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMediaDownloadSummaries() {
|
private void setMediaDownloadSummaries() {
|
||||||
|
38
src/org/thoughtcrime/securesms/util/BackupUtil.kt
Normal file
38
src/org/thoughtcrime/securesms/util/BackupUtil.kt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package org.thoughtcrime.securesms.util
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
|
import org.thoughtcrime.securesms.database.model.BackupFileRecord
|
||||||
|
import org.whispersystems.libsignal.util.ByteUtil
|
||||||
|
import java.security.SecureRandom
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
object BackupUtil {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getLastBackupTimeString(context: Context, locale: Locale): String {
|
||||||
|
val timestamp = DatabaseFactory.getLokiBackupFilesDatabase(context).getLastBackupFileTime()
|
||||||
|
if (timestamp == null) {
|
||||||
|
return context.getString(R.string.BackupUtil_never)
|
||||||
|
}
|
||||||
|
return DateUtils.getExtendedRelativeTimeSpanString(context, locale, timestamp.time)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getLastBackup(context: Context): BackupFileRecord? {
|
||||||
|
return DatabaseFactory.getLokiBackupFilesDatabase(context).getLastBackupFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun generateBackupPassphrase(): Array<String> {
|
||||||
|
val result = arrayOfNulls<String>(6)
|
||||||
|
val random = ByteArray(30)
|
||||||
|
SecureRandom().nextBytes(random)
|
||||||
|
for (i in 0..5) {
|
||||||
|
result[i] = String.format("%05d", ByteUtil.byteArray5ToLong(random, i * 5) % 100000)
|
||||||
|
}
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return result as Array<String>
|
||||||
|
}
|
||||||
|
}
|
@ -17,9 +17,10 @@ import java.util.Calendar;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
//TODO AC: Needs to be refactored to use Storage Access Framework or Media Store API.
|
//TODO AC: Needs to be refactored to use Storage Access Framework or Media Store API.
|
||||||
public class BackupUtil {
|
/** @deprecated in favor of {@link BackupUtil} */
|
||||||
|
public class BackupUtilOld {
|
||||||
|
|
||||||
private static final String TAG = BackupUtil.class.getSimpleName();
|
private static final String TAG = BackupUtilOld.class.getSimpleName();
|
||||||
|
|
||||||
public static @NonNull String getLastBackupTime(@NonNull Context context, @NonNull Locale locale) {
|
public static @NonNull String getLastBackupTime(@NonNull Context context, @NonNull Locale locale) {
|
||||||
try {
|
try {
|
Loading…
x
Reference in New Issue
Block a user