Search in sources :

Example 6 with SQLiteDatabase

use of net.zetetic.database.sqlcipher.SQLiteDatabase in project Signal-Android by WhisperSystems.

the class FullBackupExporter method internalExport.

private static void internalExport(@NonNull Context context, @NonNull AttachmentSecret attachmentSecret, @NonNull SQLiteDatabase input, @NonNull OutputStream fileOutputStream, @NonNull String passphrase, boolean closeOutputStream, @NonNull BackupCancellationSignal cancellationSignal) throws IOException {
    BackupFrameOutputStream outputStream = new BackupFrameOutputStream(fileOutputStream, passphrase);
    int count = 0;
    long estimatedCountOutside = 0L;
    try {
        outputStream.writeDatabaseVersion(input.getVersion());
        count++;
        List<String> tables = exportSchema(input, outputStream);
        count += tables.size() * TABLE_RECORD_COUNT_MULTIPLIER;
        final long estimatedCount = calculateCount(context, input, tables);
        estimatedCountOutside = estimatedCount;
        Stopwatch stopwatch = new Stopwatch("Backup");
        for (String table : tables) {
            throwIfCanceled(cancellationSignal);
            if (table.equals(MmsDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isNonExpiringMmsMessage(cursor) && isNotReleaseChannel(cursor), null, count, estimatedCount, cancellationSignal);
            } else if (table.equals(SmsDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isNonExpiringSmsMessage(cursor) && isNotReleaseChannel(cursor), null, count, estimatedCount, cancellationSignal);
            } else if (table.equals(ReactionDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMessage(input, new MessageId(CursorUtil.requireLong(cursor, ReactionDatabase.MESSAGE_ID), CursorUtil.requireBoolean(cursor, ReactionDatabase.IS_MMS))), null, count, estimatedCount, cancellationSignal);
            } else if (table.equals(MentionDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessageAndNotReleaseChannel(input, CursorUtil.requireLong(cursor, MentionDatabase.MESSAGE_ID)), null, count, estimatedCount, cancellationSignal);
            } else if (table.equals(GroupReceiptDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessageAndNotReleaseChannel(input, cursor.getLong(cursor.getColumnIndexOrThrow(GroupReceiptDatabase.MMS_ID))), null, count, estimatedCount, cancellationSignal);
            } else if (table.equals(AttachmentDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMmsMessageAndNotReleaseChannel(input, cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.MMS_ID))), (cursor, innerCount) -> exportAttachment(attachmentSecret, cursor, outputStream, innerCount, estimatedCount), count, estimatedCount, cancellationSignal);
            } else if (table.equals(StickerDatabase.TABLE_NAME)) {
                count = exportTable(table, input, outputStream, cursor -> true, (cursor, innerCount) -> exportSticker(attachmentSecret, cursor, outputStream, innerCount, estimatedCount), count, estimatedCount, cancellationSignal);
            } else if (!BLACKLISTED_TABLES.contains(table) && !table.startsWith("sqlite_")) {
                count = exportTable(table, input, outputStream, null, null, count, estimatedCount, cancellationSignal);
            }
            stopwatch.split("table::" + table);
        }
        for (BackupProtos.SharedPreference preference : TextSecurePreferences.getPreferencesToSaveToBackup(context)) {
            throwIfCanceled(cancellationSignal);
            EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count, estimatedCount));
            outputStream.write(preference);
        }
        stopwatch.split("prefs");
        count = exportKeyValues(outputStream, SignalStore.getKeysToIncludeInBackup(), count, estimatedCount, cancellationSignal);
        stopwatch.split("key_values");
        for (AvatarHelper.Avatar avatar : AvatarHelper.getAvatars(context)) {
            throwIfCanceled(cancellationSignal);
            if (avatar != null) {
                EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.PROGRESS, ++count, estimatedCount));
                outputStream.write(avatar.getFilename(), avatar.getInputStream(), avatar.getLength());
            }
        }
        stopwatch.split("avatars");
        stopwatch.stop(TAG);
        outputStream.writeEnd();
    } finally {
        if (closeOutputStream) {
            outputStream.close();
        }
        EventBus.getDefault().post(new BackupEvent(BackupEvent.Type.FINISHED, ++count, estimatedCountOutside));
    }
}
Also used : RequiresApi(androidx.annotation.RequiresApi) SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) HKDFv3(org.whispersystems.libsignal.kdf.HKDFv3) NonNull(androidx.annotation.NonNull) SecretKeySpec(javax.crypto.spec.SecretKeySpec) KeyValueDataSet(org.thoughtcrime.securesms.keyvalue.KeyValueDataSet) ModernDecryptingPartInputStream(org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream) SmsDatabase(org.thoughtcrime.securesms.database.SmsDatabase) RecipientId(org.thoughtcrime.securesms.recipients.RecipientId) Conversions(org.signal.core.util.Conversions) IdentityKeyUtil(org.thoughtcrime.securesms.crypto.IdentityKeyUtil) ReactionDatabase(org.thoughtcrime.securesms.database.ReactionDatabase) SQLiteDatabase(net.zetetic.database.sqlcipher.SQLiteDatabase) SearchDatabase(org.thoughtcrime.securesms.database.SearchDatabase) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) ApplicationDependencies(org.thoughtcrime.securesms.dependencies.ApplicationDependencies) Set(java.util.Set) Mac(javax.crypto.Mac) SetUtil(org.thoughtcrime.securesms.util.SetUtil) AvatarPickerDatabase(org.thoughtcrime.securesms.database.model.AvatarPickerDatabase) SessionDatabase(org.thoughtcrime.securesms.database.SessionDatabase) ByteString(com.google.protobuf.ByteString) Objects(java.util.Objects) Log(org.signal.core.util.logging.Log) ClassicDecryptingPartInputStream(org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream) List(java.util.List) Nullable(androidx.annotation.Nullable) MmsSmsColumns(org.thoughtcrime.securesms.database.MmsSmsColumns) DocumentFile(androidx.documentfile.provider.DocumentFile) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) InvalidKeyException(java.security.InvalidKeyException) MmsDatabase(org.thoughtcrime.securesms.database.MmsDatabase) KeyValueDatabase(org.thoughtcrime.securesms.database.KeyValueDatabase) Context(android.content.Context) StickerDatabase(org.thoughtcrime.securesms.database.StickerDatabase) AttachmentSecret(org.thoughtcrime.securesms.crypto.AttachmentSecret) PendingRetryReceiptDatabase(org.thoughtcrime.securesms.database.PendingRetryReceiptDatabase) EmojiSearchDatabase(org.thoughtcrime.securesms.database.EmojiSearchDatabase) Util(org.thoughtcrime.securesms.util.Util) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) Cipher(javax.crypto.Cipher) InvalidAlgorithmParameterException(java.security.InvalidAlgorithmParameterException) SignedPreKeyDatabase(org.thoughtcrime.securesms.database.SignedPreKeyDatabase) TextSecurePreferences(org.thoughtcrime.securesms.util.TextSecurePreferences) MentionDatabase(org.thoughtcrime.securesms.database.MentionDatabase) SenderKeySharedDatabase(org.thoughtcrime.securesms.database.SenderKeySharedDatabase) IvParameterSpec(javax.crypto.spec.IvParameterSpec) SenderKeyDatabase(org.thoughtcrime.securesms.database.SenderKeyDatabase) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) EventBus(org.greenrobot.eventbus.EventBus) LinkedList(java.util.LinkedList) Cursor(android.database.Cursor) OutputStream(java.io.OutputStream) OneTimePreKeyDatabase(org.thoughtcrime.securesms.database.OneTimePreKeyDatabase) MessageId(org.thoughtcrime.securesms.database.model.MessageId) GroupReceiptDatabase(org.thoughtcrime.securesms.database.GroupReceiptDatabase) AvatarHelper(org.thoughtcrime.securesms.profiles.AvatarHelper) FileOutputStream(java.io.FileOutputStream) TextUtils(android.text.TextUtils) IOException(java.io.IOException) ByteUtil(org.whispersystems.libsignal.util.ByteUtil) File(java.io.File) CursorUtil(org.thoughtcrime.securesms.util.CursorUtil) BadPaddingException(javax.crypto.BadPaddingException) AttachmentId(org.thoughtcrime.securesms.attachments.AttachmentId) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) Predicate(com.annimon.stream.function.Predicate) InputStream(java.io.InputStream) Stopwatch(org.thoughtcrime.securesms.util.Stopwatch) ByteString(com.google.protobuf.ByteString) AvatarHelper(org.thoughtcrime.securesms.profiles.AvatarHelper) MessageId(org.thoughtcrime.securesms.database.model.MessageId)

Example 7 with SQLiteDatabase

use of net.zetetic.database.sqlcipher.SQLiteDatabase in project Signal-Android by WhisperSystems.

the class NewDeviceServerTask method run.

@Override
public void run(@NonNull Context context, @NonNull InputStream inputStream) {
    long start = System.currentTimeMillis();
    Log.i(TAG, "Starting backup restore.");
    EventBus.getDefault().register(this);
    try {
        SQLiteDatabase database = SignalDatabase.getBackupDatabase();
        String passphrase = "deadbeef";
        BackupPassphrase.set(context, passphrase);
        FullBackupImporter.importFile(context, AttachmentSecretProvider.getInstance(context).getOrCreateAttachmentSecret(), database, inputStream, passphrase);
        SignalDatabase.upgradeRestored(database);
        NotificationChannels.restoreContactNotificationChannels(context);
        AppInitialization.onPostBackupRestore(context);
        Log.i(TAG, "Backup restore complete.");
    } catch (FullBackupImporter.DatabaseDowngradeException e) {
        Log.w(TAG, "Failed due to the backup being from a newer version of Signal.", e);
        EventBus.getDefault().post(new Status(0, Status.State.FAILURE_VERSION_DOWNGRADE));
    } catch (IOException e) {
        Log.w(TAG, e);
        EventBus.getDefault().post(new Status(0, Status.State.FAILURE_UNKNOWN));
    } finally {
        EventBus.getDefault().unregister(this);
    }
    long end = System.currentTimeMillis();
    Log.i(TAG, "Receive took: " + (end - start));
}
Also used : SQLiteDatabase(net.zetetic.database.sqlcipher.SQLiteDatabase) IOException(java.io.IOException) FullBackupImporter(org.thoughtcrime.securesms.backup.FullBackupImporter)

Example 8 with SQLiteDatabase

use of net.zetetic.database.sqlcipher.SQLiteDatabase in project Signal-Android by WhisperSystems.

the class JobDatabase method insertJobs.

public synchronized void insertJobs(@NonNull List<FullSpec> fullSpecs) {
    if (Stream.of(fullSpecs).map(FullSpec::getJobSpec).allMatch(JobSpec::isMemoryOnly)) {
        return;
    }
    SQLiteDatabase db = getWritableDatabase();
    db.beginTransaction();
    try {
        for (FullSpec fullSpec : fullSpecs) {
            insertJobSpec(db, fullSpec.getJobSpec());
            insertConstraintSpecs(db, fullSpec.getConstraintSpecs());
            insertDependencySpecs(db, fullSpec.getDependencySpecs());
        }
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}
Also used : SQLiteDatabase(net.zetetic.database.sqlcipher.SQLiteDatabase) FullSpec(org.thoughtcrime.securesms.jobmanager.persistence.FullSpec) JobSpec(org.thoughtcrime.securesms.jobmanager.persistence.JobSpec)

Example 9 with SQLiteDatabase

use of net.zetetic.database.sqlcipher.SQLiteDatabase in project Signal-Android by WhisperSystems.

the class JobDatabase method deleteJobs.

public synchronized void deleteJobs(@NonNull List<String> jobIds) {
    SQLiteDatabase db = getWritableDatabase();
    db.beginTransaction();
    try {
        for (String jobId : jobIds) {
            String[] arg = new String[] { jobId };
            db.delete(Jobs.TABLE_NAME, Jobs.JOB_SPEC_ID + " = ?", arg);
            db.delete(Constraints.TABLE_NAME, Constraints.JOB_SPEC_ID + " = ?", arg);
            db.delete(Dependencies.TABLE_NAME, Dependencies.JOB_SPEC_ID + " = ?", arg);
            db.delete(Dependencies.TABLE_NAME, Dependencies.DEPENDS_ON_JOB_SPEC_ID + " = ?", arg);
        }
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}
Also used : SQLiteDatabase(net.zetetic.database.sqlcipher.SQLiteDatabase)

Example 10 with SQLiteDatabase

use of net.zetetic.database.sqlcipher.SQLiteDatabase in project Signal-Android by WhisperSystems.

the class KeyValueDatabase method writeDataSet.

@Override
public void writeDataSet(@NonNull KeyValueDataSet dataSet, @NonNull Collection<String> removes) {
    SQLiteDatabase db = getWritableDatabase();
    db.beginTransaction();
    try {
        for (Map.Entry<String, Object> entry : dataSet.getValues().entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            Class type = dataSet.getType(key);
            ContentValues contentValues = new ContentValues(3);
            contentValues.put(KEY, key);
            if (type == byte[].class) {
                contentValues.put(VALUE, (byte[]) value);
                contentValues.put(TYPE, Type.BLOB.getId());
            } else if (type == Boolean.class) {
                contentValues.put(VALUE, (boolean) value);
                contentValues.put(TYPE, Type.BOOLEAN.getId());
            } else if (type == Float.class) {
                contentValues.put(VALUE, (float) value);
                contentValues.put(TYPE, Type.FLOAT.getId());
            } else if (type == Integer.class) {
                contentValues.put(VALUE, (int) value);
                contentValues.put(TYPE, Type.INTEGER.getId());
            } else if (type == Long.class) {
                contentValues.put(VALUE, (long) value);
                contentValues.put(TYPE, Type.LONG.getId());
            } else if (type == String.class) {
                contentValues.put(VALUE, (String) value);
                contentValues.put(TYPE, Type.STRING.getId());
            } else {
                throw new AssertionError("Unknown type: " + type);
            }
            db.insertWithOnConflict(TABLE_NAME, null, contentValues, SQLiteDatabase.CONFLICT_REPLACE);
        }
        String deleteQuery = KEY + " = ?";
        for (String remove : removes) {
            db.delete(TABLE_NAME, deleteQuery, new String[] { remove });
        }
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}
Also used : ContentValues(android.content.ContentValues) SQLiteDatabase(net.zetetic.database.sqlcipher.SQLiteDatabase) Map(java.util.Map)

Aggregations

SQLiteDatabase (net.zetetic.database.sqlcipher.SQLiteDatabase)10 ContentValues (android.content.ContentValues)3 Cursor (android.database.Cursor)2 NonNull (androidx.annotation.NonNull)2 IOException (java.io.IOException)2 LinkedList (java.util.LinkedList)2 SuppressLint (android.annotation.SuppressLint)1 Context (android.content.Context)1 TextUtils (android.text.TextUtils)1 Nullable (androidx.annotation.Nullable)1 RequiresApi (androidx.annotation.RequiresApi)1 DocumentFile (androidx.documentfile.provider.DocumentFile)1 Predicate (com.annimon.stream.function.Predicate)1 ByteString (com.google.protobuf.ByteString)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 InvalidAlgorithmParameterException (java.security.InvalidAlgorithmParameterException)1 InvalidKeyException (java.security.InvalidKeyException)1