diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 708b45450f..de0c11d55b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -312,10 +312,6 @@
android:screenOrientation="portrait"
android:theme="@style/Theme.TextSecure.DayNight.NoActionBar"
android:windowSoftInputMode="stateHidden" />
-
UPGRADE_VERSIONS = new TreeSet() {{
- add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
- add(TOFU_IDENTITIES_VERSION);
- add(CURVE25519_VERSION);
- add(ASYMMETRIC_MASTER_SECRET_FIX_VERSION);
- add(NO_V1_VERSION);
- add(SIGNED_PREKEY_VERSION);
- add(NO_DECRYPT_QUEUE_VERSION);
- add(PUSH_DECRYPT_SERIAL_ID_VERSION);
- add(MIGRATE_SESSION_PLAINTEXT);
- add(MEDIA_DOWNLOAD_CONTROLS_VERSION);
- add(REDPHONE_SUPPORT_VERSION);
- add(NO_MORE_CANONICAL_DB_VERSION);
- add(SCREENSHOTS);
- add(INTERNALIZE_CONTACTS);
- add(PERSISTENT_BLOBS);
- add(SQLCIPHER);
- add(SQLCIPHER_COMPLETE);
- add(REMOVE_CACHE);
- add(FULL_TEXT_SEARCH);
- add(BAD_IMPORT_CLEANUP);
- add(IMAGE_CACHE_CLEANUP);
- add(WORKMANAGER_MIGRATION);
- add(COLOR_MIGRATION);
- add(UNIDENTIFIED_DELIVERY);
- add(SIGNALING_KEY_DEPRECATION);
- add(CONVERSATION_SEARCH);
+// add(NO_MORE_KEY_EXCHANGE_PREFIX_VERSION);
+// add(TOFU_IDENTITIES_VERSION);
+// add(CURVE25519_VERSION);
+// add(ASYMMETRIC_MASTER_SECRET_FIX_VERSION);
+// add(NO_V1_VERSION);
+// add(SIGNED_PREKEY_VERSION);
+// add(NO_DECRYPT_QUEUE_VERSION);
+// add(PUSH_DECRYPT_SERIAL_ID_VERSION);
+// add(MIGRATE_SESSION_PLAINTEXT);
+// add(MEDIA_DOWNLOAD_CONTROLS_VERSION);
+// add(REDPHONE_SUPPORT_VERSION);
+// add(NO_MORE_CANONICAL_DB_VERSION);
+// add(SCREENSHOTS);
+// add(INTERNALIZE_CONTACTS);
+// add(PERSISTENT_BLOBS);
+// add(SQLCIPHER);
+// add(SQLCIPHER_COMPLETE);
+// add(REMOVE_CACHE);
+// add(FULL_TEXT_SEARCH);
+// add(BAD_IMPORT_CLEANUP);
+// add(IMAGE_CACHE_CLEANUP);
+// add(WORKMANAGER_MIGRATION);
+// add(COLOR_MIGRATION);
+// add(UNIDENTIFIED_DELIVERY);
+// add(SIGNALING_KEY_DEPRECATION);
+// add(CONVERSATION_SEARCH);
}};
- private MasterSecret masterSecret;
+// private MasterSecret masterSecret;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
- this.masterSecret = KeyCachingService.getMasterSecret(this);
+// this.masterSecret = KeyCachingService.getMasterSecret(this);
if (needsUpgradeTask()) {
Log.i("DatabaseUpgradeActivity", "Upgrading...");
@@ -202,160 +190,160 @@ public class DatabaseUpgradeActivity extends BaseActivity {
Context context = DatabaseUpgradeActivity.this.getApplicationContext();
Log.i("DatabaseUpgradeActivity", "Running background upgrade..");
- DatabaseFactory.getInstance(DatabaseUpgradeActivity.this)
- .onApplicationLevelUpgrade(context, masterSecret, params[0], this);
+// DatabaseFactory.getInstance(DatabaseUpgradeActivity.this)
+// .onApplicationLevelUpgrade(context, params[0], this);
- if (params[0] < CURVE25519_VERSION) {
- IdentityKeyUtil.migrateIdentityKeys(context, masterSecret);
- }
-
- if (params[0] < NO_V1_VERSION) {
- File v1sessions = new File(context.getFilesDir(), "sessions");
-
- if (v1sessions.exists() && v1sessions.isDirectory()) {
- File[] contents = v1sessions.listFiles();
-
- if (contents != null) {
- for (File session : contents) {
- session.delete();
- }
- }
-
- v1sessions.delete();
- }
- }
-
- if (params[0] < SIGNED_PREKEY_VERSION) {
-// ApplicationContext.getInstance(getApplicationContext())
-// .getJobManager()
-// .add(new CreateSignedPreKeyJob(context));
- }
-
- if (params[0] < NO_DECRYPT_QUEUE_VERSION) {
- scheduleMessagesInPushDatabase(context);
- }
-
- if (params[0] < PUSH_DECRYPT_SERIAL_ID_VERSION) {
- scheduleMessagesInPushDatabase(context);
- }
-
- if (params[0] < MIGRATE_SESSION_PLAINTEXT) {
-// new TextSecureSessionStore(context, masterSecret).migrateSessions();
-// new TextSecurePreKeyStore(context, masterSecret).migrateRecords();
-
- IdentityKeyUtil.migrateIdentityKeys(context, masterSecret);
- scheduleMessagesInPushDatabase(context);;
- }
-
- if (params[0] < MEDIA_DOWNLOAD_CONTROLS_VERSION) {
- schedulePendingIncomingParts(context);
- }
-
- if (params[0] < REDPHONE_SUPPORT_VERSION) {
- ApplicationContext.getInstance(getApplicationContext())
- .getJobManager()
- .add(new RefreshAttributesJob());
- }
-
- if (params[0] < SCREENSHOTS) {
- boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, true);
- TextSecurePreferences.setScreenSecurityEnabled(getApplicationContext(), screenSecurity);
- }
-
- if (params[0] < PERSISTENT_BLOBS) {
- File externalDir = context.getExternalFilesDir(null);
-
- if (externalDir != null && externalDir.isDirectory() && externalDir.exists()) {
- for (File blob : externalDir.listFiles()) {
- if (blob.exists() && blob.isFile()) blob.delete();
- }
- }
- }
-
- if (params[0] < INTERNALIZE_CONTACTS) {
- if (TextSecurePreferences.isPushRegistered(getApplicationContext())) {
- TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(getApplicationContext(), true);
- }
- }
-
- if (params[0] < SQLCIPHER) {
- scheduleMessagesInPushDatabase(context);
- }
-
- if (params[0] < SQLCIPHER_COMPLETE) {
- File file = context.getDatabasePath("messages.db");
- if (file != null && file.exists()) file.delete();
- }
-
- if (params[0] < REMOVE_JOURNAL) {
- File file = context.getDatabasePath("messages.db-journal");
- if (file != null && file.exists()) file.delete();
- }
-
- if (params[0] < REMOVE_CACHE) {
- try {
- FileUtils.deleteDirectoryContents(context.getCacheDir());
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
-
- if (params[0] < IMAGE_CACHE_CLEANUP) {
- try {
- FileUtils.deleteDirectoryContents(context.getExternalCacheDir());
- GlideApp.get(context).clearDiskCache();
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
-
- // This migration became unnecessary after switching away from WorkManager
-// if (params[0] < WORKMANAGER_MIGRATION) {
-// Log.i(TAG, "Beginning migration of existing jobs to WorkManager");
+// if (params[0] < CURVE25519_VERSION) {
+// IdentityKeyUtil.migrateIdentityKeys(context, masterSecret);
+// }
//
-// JobManager jobManager = ApplicationContext.getInstance(getApplicationContext()).getJobManager();
-// PersistentStorage storage = new PersistentStorage(getApplicationContext(), "TextSecureJobs", new JavaJobSerializer());
+// if (params[0] < NO_V1_VERSION) {
+// File v1sessions = new File(context.getFilesDir(), "sessions");
//
-// for (Job job : storage.getAllUnencrypted()) {
-// jobManager.add(job);
-// Log.i(TAG, "Migrated job with class '" + job.getClass().getSimpleName() + "' to run on new JobManager.");
+// if (v1sessions.exists() && v1sessions.isDirectory()) {
+// File[] contents = v1sessions.listFiles();
+//
+// if (contents != null) {
+// for (File session : contents) {
+// session.delete();
+// }
+// }
+//
+// v1sessions.delete();
// }
// }
-
- if (params[0] < COLOR_MIGRATION) {
- long startTime = System.currentTimeMillis();
- DatabaseFactory.getRecipientDatabase(context).updateSystemContactColors((name, color) -> {
- if (color != null) {
- try {
- return MaterialColor.fromSerialized(color);
- } catch (MaterialColor.UnknownColorException e) {
- Log.w(TAG, "Encountered an unknown color during legacy color migration.", e);
- return ContactColorsLegacy.generateFor(name);
- }
- }
- return ContactColorsLegacy.generateFor(name);
- });
- Log.i(TAG, "Color migration took " + (System.currentTimeMillis() - startTime) + " ms");
- }
-
- if (params[0] < UNIDENTIFIED_DELIVERY) {
- if (TextSecurePreferences.isMultiDevice(context)) {
- Log.i(TAG, "MultiDevice: Disabling UD (will be re-enabled if possible after pending refresh).");
- TextSecurePreferences.setIsUnidentifiedDeliveryEnabled(context, false);
- }
-
- Log.i(TAG, "Scheduling UD attributes refresh.");
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new RefreshAttributesJob());
- }
-
- if (params[0] < SIGNALING_KEY_DEPRECATION) {
- Log.i(TAG, "Scheduling a RefreshAttributesJob to remove the signaling key remotely.");
- ApplicationContext.getInstance(context)
- .getJobManager()
- .add(new RefreshAttributesJob());
- }
+//
+// if (params[0] < SIGNED_PREKEY_VERSION) {
+//// ApplicationContext.getInstance(getApplicationContext())
+//// .getJobManager()
+//// .add(new CreateSignedPreKeyJob(context));
+// }
+//
+// if (params[0] < NO_DECRYPT_QUEUE_VERSION) {
+// scheduleMessagesInPushDatabase(context);
+// }
+//
+// if (params[0] < PUSH_DECRYPT_SERIAL_ID_VERSION) {
+// scheduleMessagesInPushDatabase(context);
+// }
+//
+// if (params[0] < MIGRATE_SESSION_PLAINTEXT) {
+//// new TextSecureSessionStore(context, masterSecret).migrateSessions();
+//// new TextSecurePreKeyStore(context, masterSecret).migrateRecords();
+//
+// IdentityKeyUtil.migrateIdentityKeys(context, masterSecret);
+// scheduleMessagesInPushDatabase(context);;
+// }
+//
+// if (params[0] < MEDIA_DOWNLOAD_CONTROLS_VERSION) {
+// schedulePendingIncomingParts(context);
+// }
+//
+// if (params[0] < REDPHONE_SUPPORT_VERSION) {
+// ApplicationContext.getInstance(getApplicationContext())
+// .getJobManager()
+// .add(new RefreshAttributesJob());
+// }
+//
+// if (params[0] < SCREENSHOTS) {
+// boolean screenSecurity = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(TextSecurePreferences.SCREEN_SECURITY_PREF, true);
+// TextSecurePreferences.setScreenSecurityEnabled(getApplicationContext(), screenSecurity);
+// }
+//
+// if (params[0] < PERSISTENT_BLOBS) {
+// File externalDir = context.getExternalFilesDir(null);
+//
+// if (externalDir != null && externalDir.isDirectory() && externalDir.exists()) {
+// for (File blob : externalDir.listFiles()) {
+// if (blob.exists() && blob.isFile()) blob.delete();
+// }
+// }
+// }
+//
+// if (params[0] < INTERNALIZE_CONTACTS) {
+// if (TextSecurePreferences.isPushRegistered(getApplicationContext())) {
+// TextSecurePreferences.setHasSuccessfullyRetrievedDirectory(getApplicationContext(), true);
+// }
+// }
+//
+// if (params[0] < SQLCIPHER) {
+// scheduleMessagesInPushDatabase(context);
+// }
+//
+// if (params[0] < SQLCIPHER_COMPLETE) {
+// File file = context.getDatabasePath("messages.db");
+// if (file != null && file.exists()) file.delete();
+// }
+//
+// if (params[0] < REMOVE_JOURNAL) {
+// File file = context.getDatabasePath("messages.db-journal");
+// if (file != null && file.exists()) file.delete();
+// }
+//
+// if (params[0] < REMOVE_CACHE) {
+// try {
+// FileUtils.deleteDirectoryContents(context.getCacheDir());
+// } catch (IOException e) {
+// Log.w(TAG, e);
+// }
+// }
+//
+// if (params[0] < IMAGE_CACHE_CLEANUP) {
+// try {
+// FileUtils.deleteDirectoryContents(context.getExternalCacheDir());
+// GlideApp.get(context).clearDiskCache();
+// } catch (IOException e) {
+// Log.w(TAG, e);
+// }
+// }
+//
+// // This migration became unnecessary after switching away from WorkManager
+//// if (params[0] < WORKMANAGER_MIGRATION) {
+//// Log.i(TAG, "Beginning migration of existing jobs to WorkManager");
+////
+//// JobManager jobManager = ApplicationContext.getInstance(getApplicationContext()).getJobManager();
+//// PersistentStorage storage = new PersistentStorage(getApplicationContext(), "TextSecureJobs", new JavaJobSerializer());
+////
+//// for (Job job : storage.getAllUnencrypted()) {
+//// jobManager.add(job);
+//// Log.i(TAG, "Migrated job with class '" + job.getClass().getSimpleName() + "' to run on new JobManager.");
+//// }
+//// }
+//
+// if (params[0] < COLOR_MIGRATION) {
+// long startTime = System.currentTimeMillis();
+// DatabaseFactory.getRecipientDatabase(context).updateSystemContactColors((name, color) -> {
+// if (color != null) {
+// try {
+// return MaterialColor.fromSerialized(color);
+// } catch (MaterialColor.UnknownColorException e) {
+// Log.w(TAG, "Encountered an unknown color during legacy color migration.", e);
+// return ContactColorsLegacy.generateFor(name);
+// }
+// }
+// return ContactColorsLegacy.generateFor(name);
+// });
+// Log.i(TAG, "Color migration took " + (System.currentTimeMillis() - startTime) + " ms");
+// }
+//
+// if (params[0] < UNIDENTIFIED_DELIVERY) {
+// if (TextSecurePreferences.isMultiDevice(context)) {
+// Log.i(TAG, "MultiDevice: Disabling UD (will be re-enabled if possible after pending refresh).");
+// TextSecurePreferences.setIsUnidentifiedDeliveryEnabled(context, false);
+// }
+//
+// Log.i(TAG, "Scheduling UD attributes refresh.");
+// ApplicationContext.getInstance(context)
+// .getJobManager()
+// .add(new RefreshAttributesJob());
+// }
+//
+// if (params[0] < SIGNALING_KEY_DEPRECATION) {
+// Log.i(TAG, "Scheduling a RefreshAttributesJob to remove the signaling key remotely.");
+// ApplicationContext.getInstance(context)
+// .getJobManager()
+// .add(new RefreshAttributesJob());
+// }
return null;
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/MediaOverviewActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MediaOverviewActivity.java
index 0b3da4a02e..8050784a08 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/MediaOverviewActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/MediaOverviewActivity.java
@@ -62,7 +62,6 @@ import org.thoughtcrime.securesms.mms.GlideApp;
import org.thoughtcrime.securesms.permissions.Permissions;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.AttachmentUtil;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
import org.thoughtcrime.securesms.util.Util;
@@ -86,18 +85,11 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
public static final String ADDRESS_EXTRA = "address";
- private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private Recipient recipient;
- @Override
- protected void onPreCreate() {
- dynamicLanguage.onCreate(this);
- }
-
@Override
protected void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.media_overview_activity);
@@ -109,12 +101,6 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
this.viewPager.setAdapter(new MediaOverviewPagerAdapter(getSupportFragmentManager()));
}
- @Override
- public void onResume() {
- super.onResume();
- dynamicLanguage.onResume(this);
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
@@ -172,7 +158,7 @@ public class MediaOverviewActivity extends PassphraseRequiredActionBarActivity {
Bundle args = new Bundle();
args.putString(MediaOverviewGalleryFragment.ADDRESS_EXTRA, recipient.getAddress().serialize());
- args.putSerializable(MediaOverviewGalleryFragment.LOCALE_EXTRA, dynamicLanguage.getCurrentLocale());
+ args.putSerializable(MediaOverviewGalleryFragment.LOCALE_EXTRA, Locale.getDefault());
fragment.setArguments(args);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
index d31a41c8e2..d7abc45105 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/MediaPreviewActivity.java
@@ -68,12 +68,12 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.util.AttachmentUtil;
import org.thoughtcrime.securesms.util.DateUtils;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.SaveAttachmentTask;
import org.thoughtcrime.securesms.util.SaveAttachmentTask.Attachment;
import org.thoughtcrime.securesms.util.Util;
import java.io.IOException;
+import java.util.Locale;
import java.util.WeakHashMap;
import network.loki.messenger.R;
@@ -95,8 +95,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
public static final String OUTGOING_EXTRA = "outgoing";
public static final String LEFT_IS_RECENT_EXTRA = "left_is_recent";
- private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
private ViewPager mediaPager;
private View detailsContainer;
private TextView caption;
@@ -120,8 +118,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
@SuppressWarnings("ConstantConditions")
@Override
protected void onCreate(Bundle bundle, boolean ready) {
- dynamicLanguage.onCreate(this);
-
viewModel = new ViewModelProvider(this).get(MediaPreviewViewModel.class);
setContentView(R.layout.media_preview_activity);
@@ -172,7 +168,7 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
CharSequence relativeTimeSpan;
if (mediaItem.date > 0) {
- relativeTimeSpan = DateUtils.getExtendedRelativeTimeSpanString(this,dynamicLanguage.getCurrentLocale(), mediaItem.date);
+ relativeTimeSpan = DateUtils.getExtendedRelativeTimeSpanString(this, Locale.getDefault(), mediaItem.date);
} else {
relativeTimeSpan = getString(R.string.MediaPreviewActivity_draft);
}
@@ -189,7 +185,6 @@ public class MediaPreviewActivity extends PassphraseRequiredActionBarActivity im
public void onResume() {
super.onResume();
- dynamicLanguage.onResume(this);
initializeMedia();
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java
index 605794f0f3..041e92ea21 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java
@@ -55,7 +55,6 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientModifiedListener;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.util.DateUtils;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.ExpirationUtil;
import org.thoughtcrime.securesms.util.Util;
import org.session.libsignal.libsignal.util.guava.Optional;
@@ -102,15 +101,8 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
private ListView recipientsList;
private LayoutInflater inflater;
- private DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
private boolean running;
- @Override
- protected void onPreCreate() {
- dynamicLanguage.onCreate(this);
- }
-
@Override
public void onCreate(Bundle bundle, boolean ready) {
super.onCreate(bundle, ready);
@@ -125,7 +117,6 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
@Override
protected void onResume() {
super.onResume();
- dynamicLanguage.onResume(this);
assert getSupportActionBar() != null;
getSupportActionBar().setTitle("Message Details");
@@ -211,7 +202,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
sentDate.setText("-");
receivedContainer.setVisibility(View.GONE);
} else {
- Locale dateLocale = dynamicLanguage.getCurrentLocale();
+ Locale dateLocale = Locale.getDefault();
SimpleDateFormat dateFormatter = DateUtils.getDetailedDateFormatter(this, dateLocale);
sentDate.setText(dateFormatter.format(new Date(messageRecord.getDateSent())));
sentDate.setOnLongClickListener(v -> {
@@ -271,7 +262,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity
toFrom.setVisibility(View.GONE);
separator.setVisibility(View.GONE);
}
- conversationItem.bind(messageRecord, Optional.absent(), Optional.absent(), glideRequests, dynamicLanguage.getCurrentLocale(), new HashSet<>(), recipient, null, false);
+ conversationItem.bind(messageRecord, Optional.absent(), Optional.absent(), glideRequests, Locale.getDefault(), new HashSet<>(), recipient, null, false);
recipientsList.setAdapter(new MessageDetailsRecipientAdapter(this, glideRequests, messageRecord, recipients, isPushGroup));
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseActivity.java
deleted file mode 100644
index 318cbf73be..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseActivity.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-import org.thoughtcrime.securesms.logging.Log;
-
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.service.KeyCachingService;
-
-
-/**
- * Base Activity for changing/prompting local encryption passphrase.
- *
- * @author Moxie Marlinspike
- */
-public abstract class PassphraseActivity extends BaseActionBarActivity {
-
- private static final String TAG = PassphraseActivity.class.getSimpleName();
-
- private KeyCachingService keyCachingService;
- private MasterSecret masterSecret;
-
- protected void setMasterSecret(MasterSecret masterSecret) {
- this.masterSecret = masterSecret;
- Intent bindIntent = new Intent(this, KeyCachingService.class);
- startService(bindIntent);
- bindService(bindIntent, serviceConnection, Context.BIND_AUTO_CREATE);
- }
-
- protected abstract void cleanup();
-
- private ServiceConnection serviceConnection = new ServiceConnection() {
- @Override
- public void onServiceConnected(ComponentName className, IBinder service) {
- keyCachingService = ((KeyCachingService.KeySetBinder)service).getService();
- keyCachingService.setMasterSecret(masterSecret);
-
- PassphraseActivity.this.unbindService(PassphraseActivity.this.serviceConnection);
-
- masterSecret = null;
- cleanup();
-
- Intent nextIntent = getIntent().getParcelableExtra("next_intent");
- if (nextIntent != null) {
- try {
- startActivity(nextIntent);
- } catch (java.lang.SecurityException e) {
- Log.w(TAG, "Access permission not passed from PassphraseActivity, retry sharing.");
- }
- }
- finish();
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- keyCachingService = null;
- }
- };
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseChangeActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseChangeActivity.java
deleted file mode 100644
index 666f4c5d3f..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseChangeActivity.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms;
-
-import android.content.Context;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.Editable;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Button;
-import android.widget.EditText;
-
-import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
-import org.thoughtcrime.securesms.util.DynamicTheme;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-
-import network.loki.messenger.R;
-
-/**
- * Activity for changing a user's local encryption passphrase.
- *
- * @author Moxie Marlinspike
- */
-
-public class PassphraseChangeActivity extends PassphraseActivity {
-
- private DynamicTheme dynamicTheme = new DynamicTheme();
- private DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
- private EditText originalPassphrase;
- private EditText newPassphrase;
- private EditText repeatPassphrase;
- private Button okButton;
- private Button cancelButton;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- dynamicTheme.onCreate(this);
- dynamicLanguage.onCreate(this);
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.change_passphrase_activity);
-
- initializeResources();
- }
-
- @Override
- public void onResume() {
- super.onResume();
- dynamicTheme.onResume(this);
- dynamicLanguage.onResume(this);
- }
-
- private void initializeResources() {
- this.originalPassphrase = (EditText) findViewById(R.id.old_passphrase );
- this.newPassphrase = (EditText) findViewById(R.id.new_passphrase );
- this.repeatPassphrase = (EditText) findViewById(R.id.repeat_passphrase );
-
- this.okButton = (Button ) findViewById(R.id.ok_button );
- this.cancelButton = (Button ) findViewById(R.id.cancel_button );
-
- this.okButton.setOnClickListener(new OkButtonClickListener());
- this.cancelButton.setOnClickListener(new CancelButtonClickListener());
-
- if (TextSecurePreferences.isPasswordDisabled(this)) {
- this.originalPassphrase.setVisibility(View.GONE);
- } else {
- this.originalPassphrase.setVisibility(View.VISIBLE);
- }
- }
-
- private void verifyAndSavePassphrases() {
- Editable originalText = this.originalPassphrase.getText();
- Editable newText = this.newPassphrase.getText();
- Editable repeatText = this.repeatPassphrase.getText();
-
- String original = (originalText == null ? "" : originalText.toString());
- String passphrase = (newText == null ? "" : newText.toString());
- String passphraseRepeat = (repeatText == null ? "" : repeatText.toString());
-
- if (TextSecurePreferences.isPasswordDisabled(this)) {
- original = MasterSecretUtil.UNENCRYPTED_PASSPHRASE;
- }
-
- if (!passphrase.equals(passphraseRepeat)) {
- this.newPassphrase.setText("");
- this.repeatPassphrase.setText("");
- this.newPassphrase.setError(getString(R.string.PassphraseChangeActivity_passphrases_dont_match_exclamation));
- this.newPassphrase.requestFocus();
- } else if (passphrase.equals("")) {
- this.newPassphrase.setError(getString(R.string.PassphraseChangeActivity_enter_new_passphrase_exclamation));
- this.newPassphrase.requestFocus();
- } else {
- new ChangePassphraseTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, original, passphrase);
- }
- }
-
- private class CancelButtonClickListener implements OnClickListener {
- public void onClick(View v) {
- finish();
- }
- }
-
- private class OkButtonClickListener implements OnClickListener {
- public void onClick(View v) {
- verifyAndSavePassphrases();
- }
- }
-
- private class ChangePassphraseTask extends AsyncTask {
- private final Context context;
-
- public ChangePassphraseTask(Context context) {
- this.context = context;
- }
-
- @Override
- protected void onPreExecute() {
- okButton.setEnabled(false);
- }
-
- @Override
- protected MasterSecret doInBackground(String... params) {
- try {
- MasterSecret masterSecret = MasterSecretUtil.changeMasterSecretPassphrase(context, params[0], params[1]);
- TextSecurePreferences.setPasswordDisabled(context, false);
-
- return masterSecret;
-
- } catch (InvalidPassphraseException e) {
- Log.w(PassphraseChangeActivity.class.getSimpleName(), e);
- return null;
- }
- }
-
- @Override
- protected void onPostExecute(MasterSecret masterSecret) {
- okButton.setEnabled(true);
-
- if (masterSecret != null) {
- setMasterSecret(masterSecret);
- } else {
- originalPassphrase.setText("");
- originalPassphrase.setError(getString(R.string.PassphraseChangeActivity_incorrect_old_passphrase_exclamation));
- originalPassphrase.requestFocus();
- }
- }
- }
-
- @Override
- protected void cleanup() {
- this.originalPassphrase = null;
- this.newPassphrase = null;
- this.repeatPassphrase = null;
-
- System.gc();
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseCreateActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseCreateActivity.java
deleted file mode 100644
index 8bdbedc4dc..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseCreateActivity.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms;
-
-import android.os.AsyncTask;
-import android.os.Bundle;
-
-import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-import org.thoughtcrime.securesms.util.Util;
-import org.thoughtcrime.securesms.util.VersionTracker;
-
-import network.loki.messenger.R;
-
-/**
- * Activity for creating a user's local encryption passphrase.
- *
- * @author Moxie Marlinspike
- */
-
-public class PassphraseCreateActivity extends PassphraseActivity {
-
- public PassphraseCreateActivity() { }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.create_passphrase_activity);
-
- initializeResources();
- }
-
- private void initializeResources() {
- new SecretGenerator().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
- }
-
- private class SecretGenerator extends AsyncTask {
- private MasterSecret masterSecret;
-
- @Override
- protected void onPreExecute() {
- }
-
- @Override
- protected Void doInBackground(String... params) {
- String passphrase = params[0];
- masterSecret = MasterSecretUtil.generateMasterSecret(PassphraseCreateActivity.this,
- passphrase);
-
- MasterSecretUtil.generateAsymmetricMasterSecret(PassphraseCreateActivity.this, masterSecret);
- IdentityKeyUtil.generateIdentityKeyPair(PassphraseCreateActivity.this);
- VersionTracker.updateLastSeenVersion(PassphraseCreateActivity.this);
-
- TextSecurePreferences.setLastExperienceVersionCode(PassphraseCreateActivity.this, Util.getCanonicalVersionCode());
- TextSecurePreferences.setPasswordDisabled(PassphraseCreateActivity.this, true);
- TextSecurePreferences.setReadReceiptsEnabled(PassphraseCreateActivity.this, true);
- TextSecurePreferences.setTypingIndicatorsEnabled(PassphraseCreateActivity.this, true);
- TextSecurePreferences.setHasSeenWelcomeScreen(PassphraseCreateActivity.this, false);
-
- return null;
- }
-
- @Override
- protected void onPostExecute(Void param) {
- setMasterSecret(masterSecret);
- }
- }
-
- @Override
- protected void cleanup() {
- System.gc();
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java
index 20d67b672a..2f9da6efe5 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/PassphrasePromptActivity.java
@@ -18,66 +18,43 @@ package org.thoughtcrime.securesms;
import android.animation.Animator;
import android.app.KeyguardManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.graphics.PorterDuff;
-import android.os.Build;
import android.os.Bundle;
-import android.text.Editable;
-import android.text.InputType;
+import android.os.IBinder;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.RelativeSizeSpan;
import android.text.style.TypefaceSpan;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.BounceInterpolator;
import android.view.animation.TranslateAnimation;
-import android.view.inputmethod.EditorInfo;
import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageButton;
import android.widget.ImageView;
-import android.widget.TextView;
import androidx.core.hardware.fingerprint.FingerprintManagerCompat;
import androidx.core.os.CancellationSignal;
import org.thoughtcrime.securesms.animation.AnimationCompleteListener;
import org.thoughtcrime.securesms.components.AnimatingToggle;
-import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
+import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import network.loki.messenger.R;
-/**
- * Activity that prompts for a user's passphrase.
- *
- * @author Moxie Marlinspike
- */
-public class PassphrasePromptActivity extends PassphraseActivity {
+//TODO Rename to screen lock activity and refactor to Kotlin.
+public class PassphrasePromptActivity extends BaseActionBarActivity {
private static final String TAG = PassphrasePromptActivity.class.getSimpleName();
- private DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
- private View passphraseAuthContainer;
private ImageView fingerprintPrompt;
private Button lockScreenButton;
- private EditText passphraseText;
- private ImageButton showButton;
- private ImageButton hideButton;
private AnimatingToggle visibilityToggle;
private FingerprintManagerCompat fingerprintManager;
@@ -87,20 +64,34 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private boolean authenticated;
private boolean failure;
+ private KeyCachingService keyCachingService;
+
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate()");
- dynamicLanguage.onCreate(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.prompt_passphrase_activity);
initializeResources();
+
+ // Start and bind to the KeyCachingService instance.
+ Intent bindIntent = new Intent(this, KeyCachingService.class);
+ startService(bindIntent);
+ bindService(bindIntent, new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ keyCachingService = ((KeyCachingService.KeySetBinder)service).getService();
+ }
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ keyCachingService = null;
+ }
+ }, Context.BIND_AUTO_CREATE);
}
@Override
public void onResume() {
super.onResume();
- dynamicLanguage.onResume(this);
setLockTypeVisibility();
@@ -126,26 +117,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
setIntent(intent);
}
- @Override
- public boolean onPrepareOptionsMenu(Menu menu) {
- MenuInflater inflater = this.getMenuInflater();
- menu.clear();
-
- // inflater.inflate(R.menu.log_submit, menu);
- super.onPrepareOptionsMenu(menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- super.onOptionsItemSelected(item);
- switch (item.getItemId()) {
- case R.id.menu_submit_debug_logs: handleLogSubmit(); return true;
- }
-
- return false;
- }
-
@Override
public void onActivityResult(int requestCode, int resultcode, Intent data) {
super.onActivityResult(requestCode, resultcode, data);
@@ -159,57 +130,26 @@ public class PassphrasePromptActivity extends PassphraseActivity {
}
}
- private void handleLogSubmit() {
- Intent intent = new Intent(this, LogSubmitActivity.class);
- startActivity(intent);
- }
-
- private void handlePassphrase() {
- try {
- Editable text = passphraseText.getText();
- String passphrase = (text == null ? "" : text.toString());
- MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, passphrase);
-
- setMasterSecret(masterSecret);
- } catch (InvalidPassphraseException ipe) {
- passphraseText.setText("");
- passphraseText.setError(
- getString(R.string.PassphrasePromptActivity_invalid_passphrase_exclamation));
- }
- }
-
private void handleAuthenticated() {
- try {
- authenticated = true;
-
- MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
- setMasterSecret(masterSecret);
- } catch (InvalidPassphraseException e) {
- throw new AssertionError(e);
- }
- }
+ authenticated = true;
+ //TODO Replace with a proper call.
+ keyCachingService.setMasterSecret(new Object());
- private void setPassphraseVisibility(boolean visibility) {
- int cursorPosition = passphraseText.getSelectionStart();
- if (visibility) {
- passphraseText.setInputType(InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
- } else {
- passphraseText.setInputType(InputType.TYPE_CLASS_TEXT |
- InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ // Finish and proceed with the next intent.
+ Intent nextIntent = getIntent().getParcelableExtra("next_intent");
+ if (nextIntent != null) {
+ startActivity(nextIntent);
+// try {
+// startActivity(nextIntent);
+// } catch (java.lang.SecurityException e) {
+// Log.w(TAG, "Access permission not passed from PassphraseActivity, retry sharing.");
+// }
}
- passphraseText.setSelection(cursorPosition);
+ finish();
}
private void initializeResources() {
-
- ImageButton okButton = findViewById(R.id.ok_button);
-
- showButton = findViewById(R.id.passphrase_visibility);
- hideButton = findViewById(R.id.passphrase_visibility_off);
visibilityToggle = findViewById(R.id.button_toggle);
- passphraseText = findViewById(R.id.passphrase_edit);
- passphraseAuthContainer = findViewById(R.id.password_auth_container);
fingerprintPrompt = findViewById(R.id.fingerprint_auth_container);
lockScreenButton = findViewById(R.id.lock_screen_auth_container);
fingerprintManager = FingerprintManagerCompat.from(this);
@@ -220,13 +160,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
hint.setSpan(new RelativeSizeSpan(0.9f), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
hint.setSpan(new TypefaceSpan("sans-serif"), 0, hint.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
- passphraseText.setHint(hint);
- okButton.setOnClickListener(new OkButtonClickListener());
- showButton.setOnClickListener(new ShowButtonOnClickListener());
- hideButton.setOnClickListener(new HideButtonOnClickListener());
- passphraseText.setOnEditorActionListener(new PassphraseActionListener());
- passphraseText.setImeActionLabel(getString(R.string.prompt_passphrase_activity__unlock), EditorInfo.IME_ACTION_DONE);
-
fingerprintPrompt.setImageResource(R.drawable.ic_fingerprint_white_48dp);
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.signal_primary), PorterDuff.Mode.SRC_IN);
@@ -235,8 +168,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
private void setLockTypeVisibility() {
if (TextSecurePreferences.isScreenLockEnabled(this)) {
- passphraseAuthContainer.setVisibility(View.GONE);
-
if (fingerprintManager.isHardwareDetected() && fingerprintManager.hasEnrolledFingerprints()) {
fingerprintPrompt.setVisibility(View.VISIBLE);
lockScreenButton.setVisibility(View.GONE);
@@ -245,7 +176,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
lockScreenButton.setVisibility(View.VISIBLE);
}
} else {
- passphraseAuthContainer.setVisibility(View.VISIBLE);
fingerprintPrompt.setVisibility(View.GONE);
lockScreenButton.setVisibility(View.GONE);
}
@@ -266,13 +196,10 @@ public class PassphrasePromptActivity extends PassphraseActivity {
Log.i(TAG, "Listening for fingerprints...");
fingerprintCancellationSignal = new CancellationSignal();
fingerprintManager.authenticate(null, 0, fingerprintCancellationSignal, fingerprintListener, null);
- } else if (Build.VERSION.SDK_INT >= 21){
+ } else {
Log.i(TAG, "firing intent...");
Intent intent = keyguardManager.createConfirmDeviceCredentialIntent("Unlock Session", "");
startActivityForResult(intent, 1);
- } else {
- Log.w(TAG, "Not compatible...");
- handleAuthenticated();
}
}
@@ -282,54 +209,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
}
}
- private class PassphraseActionListener implements TextView.OnEditorActionListener {
- @Override
- public boolean onEditorAction(TextView exampleView, int actionId, KeyEvent keyEvent) {
- if ((keyEvent == null && actionId == EditorInfo.IME_ACTION_DONE) ||
- (keyEvent != null && keyEvent.getAction() == KeyEvent.ACTION_DOWN &&
- (actionId == EditorInfo.IME_NULL)))
- {
- handlePassphrase();
- return true;
- } else if (keyEvent != null && keyEvent.getAction() == KeyEvent.ACTION_UP &&
- actionId == EditorInfo.IME_NULL)
- {
- return true;
- }
-
- return false;
- }
- }
-
- private class OkButtonClickListener implements OnClickListener {
- @Override
- public void onClick(View v) {
- handlePassphrase();
- }
- }
-
- private class ShowButtonOnClickListener implements OnClickListener {
- @Override
- public void onClick(View v) {
- visibilityToggle.display(hideButton);
- setPassphraseVisibility(true);
- }
- }
-
- private class HideButtonOnClickListener implements OnClickListener {
- @Override
- public void onClick(View v) {
- visibilityToggle.display(showButton);
- setPassphraseVisibility(false);
- }
- }
-
- @Override
- protected void cleanup() {
- this.passphraseText.setText("");
- System.gc();
- }
-
private class FingerprintListener extends FingerprintManagerCompat.AuthenticationCallback {
@Override
public void onAuthenticationError(int errMsgId, CharSequence errString) {
@@ -356,7 +235,6 @@ public class PassphrasePromptActivity extends PassphraseActivity {
@Override
public void onAuthenticationFailed() {
Log.w(TAG, "onAuthenticatoinFailed()");
- FingerprintManagerCompat.AuthenticationCallback callback = this;
fingerprintPrompt.setImageResource(R.drawable.ic_close_white_48dp);
fingerprintPrompt.getBackground().setColorFilter(getResources().getColor(R.color.red_500), PorterDuff.Mode.SRC_IN);
@@ -380,6 +258,5 @@ public class PassphrasePromptActivity extends PassphraseActivity {
fingerprintPrompt.startAnimation(shake);
}
-
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
index 720e4aa1fb..4b7960d50e 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
@@ -10,8 +10,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.activities.HomeActivity;
import org.thoughtcrime.securesms.loki.activities.LandingActivity;
@@ -27,7 +25,6 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
public static final String LOCALE_EXTRA = "locale_extra";
private static final int STATE_NORMAL = 0;
- private static final int STATE_CREATE_PASSPHRASE = 1;
private static final int STATE_PROMPT_PASSPHRASE = 2;
private static final int STATE_UPGRADE_DATABASE = 3;
private static final int STATE_PROMPT_PUSH_REGISTRATION = 4;
@@ -118,7 +115,6 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
Log.i(TAG, "routeApplicationState(), state: " + state);
switch (state) {
- case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent();
case STATE_WELCOME_SCREEN: return getWelcomeIntent();
@@ -129,9 +125,7 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
}
private int getApplicationState(boolean locked) {
- if (!MasterSecretUtil.isPassphraseInitialized(this)) {
- return STATE_CREATE_PASSPHRASE;
- } else if (locked) {
+ if (locked) {
return STATE_PROMPT_PASSPHRASE;
} else if (DatabaseUpgradeActivity.isUpdate(this)) {
return STATE_UPGRADE_DATABASE;
@@ -148,10 +142,6 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
}
}
- private Intent getCreatePassphraseIntent() {
- return getRoutedIntent(PassphraseCreateActivity.class, getIntent());
- }
-
private Intent getPromptPassphraseIntent() {
return getRoutedIntent(PassphrasePromptActivity.class, getIntent());
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java
index acbb775f4e..45be4d26c7 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/ShareActivity.java
@@ -48,7 +48,6 @@ import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.providers.BlobProvider;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.stickers.StickerLocator;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java
index febd2cc5a4..624c029f88 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java
@@ -48,8 +48,6 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
-import androidx.core.app.ActivityCompat;
-import androidx.core.app.ActivityOptionsCompat;
import androidx.fragment.app.Fragment;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
@@ -66,8 +64,6 @@ import org.thoughtcrime.securesms.ShareActivity;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.components.ConversationTypingView;
import org.thoughtcrime.securesms.components.recyclerview.SmoothScrollingLinearLayoutManager;
-import org.thoughtcrime.securesms.contactshare.Contact;
-import org.thoughtcrime.securesms.contactshare.ContactUtil;
import org.thoughtcrime.securesms.conversation.ConversationAdapter.HeaderViewHolder;
import org.thoughtcrime.securesms.conversation.ConversationAdapter.ItemClickListener;
import org.thoughtcrime.securesms.database.Address;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java
deleted file mode 100644
index b625876729..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- * Copyright (C) 2013 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.crypto;
-
-import org.thoughtcrime.securesms.util.Base64;
-import org.thoughtcrime.securesms.util.Util;
-import org.session.libsignal.libsignal.InvalidKeyException;
-import org.session.libsignal.libsignal.InvalidMessageException;
-import org.session.libsignal.libsignal.ecc.Curve;
-import org.session.libsignal.libsignal.ecc.ECKeyPair;
-import org.session.libsignal.libsignal.ecc.ECPrivateKey;
-import org.session.libsignal.libsignal.ecc.ECPublicKey;
-import org.thoughtcrime.securesms.util.Conversions;
-
-import java.io.IOException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * This class is used to asymmetricly encrypt local data. This is used in the case
- * where TextSecure receives an SMS, but the user's local encryption passphrase is
- * not cached (either because of a timeout, or because it hasn't yet been entered).
- *
- * In this case, we have access to the public key of a local keypair. We encrypt
- * the message with this, and put it into the DB. When the user enters their passphrase,
- * we can get access to the private key of the local keypair, decrypt the message, and
- * replace it into the DB with symmetric encryption.
- *
- * The encryption protocol is as follows:
- *
- * 1) Generate an ephemeral keypair.
- * 2) Do ECDH with the public key of the local durable keypair.
- * 3) Do KMF with the ECDH result to obtain a master secret.
- * 4) Encrypt the message with that master secret.
- *
- * @author Moxie Marlinspike
- *
- */
-public class AsymmetricMasterCipher {
-
- private final AsymmetricMasterSecret asymmetricMasterSecret;
-
- public AsymmetricMasterCipher(AsymmetricMasterSecret asymmetricMasterSecret) {
- this.asymmetricMasterSecret = asymmetricMasterSecret;
- }
-
- public byte[] encryptBytes(byte[] body) {
- try {
- ECPublicKey theirPublic = asymmetricMasterSecret.getDjbPublicKey();
- ECKeyPair ourKeyPair = Curve.generateKeyPair();
- byte[] secret = Curve.calculateAgreement(theirPublic, ourKeyPair.getPrivateKey());
- MasterCipher masterCipher = getMasterCipherForSecret(secret);
- byte[] encryptedBodyBytes = masterCipher.encryptBytes(body);
-
- PublicKey ourPublicKey = new PublicKey(31337, ourKeyPair.getPublicKey());
- byte[] publicKeyBytes = ourPublicKey.serialize();
-
- return Util.combine(publicKeyBytes, encryptedBodyBytes);
- } catch (InvalidKeyException e) {
- throw new AssertionError(e);
- }
- }
-
- public byte[] decryptBytes(byte[] combined) throws IOException, InvalidMessageException {
- try {
- byte[][] parts = Util.split(combined, PublicKey.KEY_SIZE, combined.length - PublicKey.KEY_SIZE);
- PublicKey theirPublicKey = new PublicKey(parts[0], 0);
-
- ECPrivateKey ourPrivateKey = asymmetricMasterSecret.getPrivateKey();
- byte[] secret = Curve.calculateAgreement(theirPublicKey.getKey(), ourPrivateKey);
- MasterCipher masterCipher = getMasterCipherForSecret(secret);
-
- return masterCipher.decryptBytes(parts[1]);
- } catch (InvalidKeyException e) {
- throw new InvalidMessageException(e);
- }
- }
-
- public String decryptBody(String body) throws IOException, InvalidMessageException {
- byte[] combined = Base64.decode(body);
- return new String(decryptBytes(combined));
- }
-
- public String encryptBody(String body) {
- return Base64.encodeBytes(encryptBytes(body.getBytes()));
- }
-
- private MasterCipher getMasterCipherForSecret(byte[] secretBytes) {
- SecretKeySpec cipherKey = deriveCipherKey(secretBytes);
- SecretKeySpec macKey = deriveMacKey(secretBytes);
- MasterSecret masterSecret = new MasterSecret(cipherKey, macKey);
-
- return new MasterCipher(masterSecret);
- }
-
- private SecretKeySpec deriveMacKey(byte[] secretBytes) {
- byte[] digestedBytes = getDigestedBytes(secretBytes, 1);
- byte[] macKeyBytes = new byte[20];
-
- System.arraycopy(digestedBytes, 0, macKeyBytes, 0, macKeyBytes.length);
- return new SecretKeySpec(macKeyBytes, "HmacSHA1");
- }
-
- private SecretKeySpec deriveCipherKey(byte[] secretBytes) {
- byte[] digestedBytes = getDigestedBytes(secretBytes, 0);
- byte[] cipherKeyBytes = new byte[16];
-
- System.arraycopy(digestedBytes, 0, cipherKeyBytes, 0, cipherKeyBytes.length);
- return new SecretKeySpec(cipherKeyBytes, "AES");
- }
-
- private byte[] getDigestedBytes(byte[] secretBytes, int iteration) {
- try {
- Mac mac = Mac.getInstance("HmacSHA256");
- mac.init(new SecretKeySpec(secretBytes, "HmacSHA256"));
- return mac.doFinal(Conversions.intToByteArray(iteration));
- } catch (NoSuchAlgorithmException | java.security.InvalidKeyException e) {
- throw new AssertionError(e);
- }
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java
index 47cf0831ca..2c5ba26e4b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java
@@ -40,15 +40,14 @@ import java.util.List;
*
* @author Moxie Marlinspike
*/
-
+//TODO AC: Delete
public class IdentityKeyUtil {
+ private static final String MASTER_SECRET_UTIL_PREFERENCES_NAME = "SecureSMS-Preferences";
+
@SuppressWarnings("unused")
private static final String TAG = IdentityKeyUtil.class.getSimpleName();
- private static final String IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_public_curve25519";
- private static final String IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF = "pref_identity_private_curve25519";
-
public static final String IDENTITY_PUBLIC_KEY_PREF = "pref_identity_public_v3";
public static final String IDENTITY_PRIVATE_KEY_PREF = "pref_identity_private_v3";
public static final String ED25519_PUBLIC_KEY = "pref_ed25519_public_key";
@@ -56,7 +55,7 @@ public class IdentityKeyUtil {
public static final String LOKI_SEED = "loki_seed";
public static boolean hasIdentityKey(Context context) {
- SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
+ SharedPreferences preferences = context.getSharedPreferences(MASTER_SECRET_UTIL_PREFERENCES_NAME, 0);
return
preferences.contains(IDENTITY_PUBLIC_KEY_PREF) &&
@@ -87,63 +86,38 @@ public class IdentityKeyUtil {
}
}
- public static void generateIdentityKeyPair(Context context) {
- ECKeyPair keyPair = Curve.generateKeyPair();;
- IdentityKey publicKey = new IdentityKey(keyPair.getPublicKey());
- ECPrivateKey privateKey = keyPair.getPrivateKey();
- save(context, IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(publicKey.serialize()));
- save(context, IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(privateKey.serialize()));
- }
-
- public static void migrateIdentityKeys(@NonNull Context context,
- @NonNull MasterSecret masterSecret)
- {
- if (!hasIdentityKey(context)) {
- if (hasLegacyIdentityKeys(context)) {
- IdentityKeyPair legacyPair = getLegacyIdentityKeyPair(context, masterSecret);
-
- save(context, IDENTITY_PUBLIC_KEY_PREF, Base64.encodeBytes(legacyPair.getPublicKey().serialize()));
- save(context, IDENTITY_PRIVATE_KEY_PREF, Base64.encodeBytes(legacyPair.getPrivateKey().serialize()));
-
- delete(context, IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF);
- delete(context, IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF);
- } else {
- generateIdentityKeyPair(context);
- }
- }
- }
-
public static List getBackupRecords(@NonNull Context context) {
- SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
+ final String prefName = MASTER_SECRET_UTIL_PREFERENCES_NAME;
+ SharedPreferences preferences = context.getSharedPreferences(prefName, 0);
LinkedList prefList = new LinkedList<>();
prefList.add(BackupProtos.SharedPreference.newBuilder()
- .setFile(MasterSecretUtil.PREFERENCES_NAME)
+ .setFile(prefName)
.setKey(IDENTITY_PUBLIC_KEY_PREF)
.setValue(preferences.getString(IDENTITY_PUBLIC_KEY_PREF, null))
.build());
prefList.add(BackupProtos.SharedPreference.newBuilder()
- .setFile(MasterSecretUtil.PREFERENCES_NAME)
+ .setFile(prefName)
.setKey(IDENTITY_PRIVATE_KEY_PREF)
.setValue(preferences.getString(IDENTITY_PRIVATE_KEY_PREF, null))
.build());
if (preferences.contains(ED25519_PUBLIC_KEY)) {
prefList.add(BackupProtos.SharedPreference.newBuilder()
- .setFile(MasterSecretUtil.PREFERENCES_NAME)
+ .setFile(prefName)
.setKey(ED25519_PUBLIC_KEY)
.setValue(preferences.getString(ED25519_PUBLIC_KEY, null))
.build());
}
if (preferences.contains(ED25519_SECRET_KEY)) {
prefList.add(BackupProtos.SharedPreference.newBuilder()
- .setFile(MasterSecretUtil.PREFERENCES_NAME)
+ .setFile(prefName)
.setKey(ED25519_SECRET_KEY)
.setValue(preferences.getString(ED25519_SECRET_KEY, null))
.build());
}
prefList.add(BackupProtos.SharedPreference.newBuilder()
- .setFile(MasterSecretUtil.PREFERENCES_NAME)
+ .setFile(prefName)
.setKey(LOKI_SEED)
.setValue(preferences.getString(LOKI_SEED, null))
.build());
@@ -151,34 +125,13 @@ public class IdentityKeyUtil {
return prefList;
}
- private static boolean hasLegacyIdentityKeys(Context context) {
- return
- retrieve(context, IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF) != null &&
- retrieve(context, IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF) != null;
- }
-
- private static IdentityKeyPair getLegacyIdentityKeyPair(@NonNull Context context,
- @NonNull MasterSecret masterSecret)
- {
- try {
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- byte[] publicKeyBytes = Base64.decode(retrieve(context, IDENTITY_PUBLIC_KEY_CIPHERTEXT_LEGACY_PREF));
- IdentityKey identityKey = new IdentityKey(publicKeyBytes, 0);
- ECPrivateKey privateKey = masterCipher.decryptKey(Base64.decode(retrieve(context, IDENTITY_PRIVATE_KEY_CIPHERTEXT_LEGACY_PREF)));
-
- return new IdentityKeyPair(identityKey, privateKey);
- } catch (IOException | InvalidKeyException e) {
- throw new AssertionError(e);
- }
- }
-
public static String retrieve(Context context, String key) {
- SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
+ SharedPreferences preferences = context.getSharedPreferences(MASTER_SECRET_UTIL_PREFERENCES_NAME, 0);
return preferences.getString(key, null);
}
public static void save(Context context, String key, String value) {
- SharedPreferences preferences = context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0);
+ SharedPreferences preferences = context.getSharedPreferences(MASTER_SECRET_UTIL_PREFERENCES_NAME, 0);
Editor preferencesEditor = preferences.edit();
preferencesEditor.putString(key, value);
@@ -186,6 +139,6 @@ public class IdentityKeyUtil {
}
public static void delete(Context context, String key) {
- context.getSharedPreferences(MasterSecretUtil.PREFERENCES_NAME, 0).edit().remove(key).commit();
+ context.getSharedPreferences(MASTER_SECRET_UTIL_PREFERENCES_NAME, 0).edit().remove(key).commit();
}
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterCipher.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterCipher.java
deleted file mode 100644
index ca6bfca465..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterCipher.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- * Copyright (C) 2013 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.crypto;
-
-import androidx.annotation.NonNull;
-import org.thoughtcrime.securesms.logging.Log;
-
-import org.thoughtcrime.securesms.util.Base64;
-import org.thoughtcrime.securesms.util.Hex;
-import org.session.libsignal.libsignal.InvalidMessageException;
-import org.session.libsignal.libsignal.ecc.Curve;
-import org.session.libsignal.libsignal.ecc.ECPrivateKey;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.Mac;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Class that handles encryption for local storage.
- *
- * The protocol format is roughly:
- *
- * 1) 16 byte random IV.
- * 2) AES-CBC(plaintext)
- * 3) HMAC-SHA1 of 1 and 2
- *
- * @author Moxie Marlinspike
- */
-
-public class MasterCipher {
-
- private static final String TAG = MasterCipher.class.getSimpleName();
-
- private final MasterSecret masterSecret;
- private final Cipher encryptingCipher;
- private final Cipher decryptingCipher;
- private final Mac hmac;
-
- public MasterCipher(MasterSecret masterSecret) {
- try {
- this.masterSecret = masterSecret;
- this.encryptingCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- this.decryptingCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- this.hmac = Mac.getInstance("HmacSHA1");
- } catch (NoSuchPaddingException | NoSuchAlgorithmException nspe) {
- throw new AssertionError(nspe);
- }
- }
-
- public byte[] encryptKey(ECPrivateKey privateKey) {
- return encryptBytes(privateKey.serialize());
- }
-
- public String encryptBody(@NonNull String body) {
- return encryptAndEncodeBytes(body.getBytes());
- }
-
- public String decryptBody(String body) throws InvalidMessageException {
- return new String(decodeAndDecryptBytes(body));
- }
-
- public ECPrivateKey decryptKey(byte[] key)
- throws org.session.libsignal.libsignal.InvalidKeyException
- {
- try {
- return Curve.decodePrivatePoint(decryptBytes(key));
- } catch (InvalidMessageException ime) {
- throw new org.session.libsignal.libsignal.InvalidKeyException(ime);
- }
- }
-
- public byte[] decryptBytes(@NonNull byte[] decodedBody) throws InvalidMessageException {
- try {
- Mac mac = getMac(masterSecret.getMacKey());
- byte[] encryptedBody = verifyMacBody(mac, decodedBody);
-
- Cipher cipher = getDecryptingCipher(masterSecret.getEncryptionKey(), encryptedBody);
- byte[] encrypted = getDecryptedBody(cipher, encryptedBody);
-
- return encrypted;
- } catch (GeneralSecurityException ge) {
- throw new InvalidMessageException(ge);
- }
- }
-
- public byte[] encryptBytes(byte[] body) {
- try {
- Cipher cipher = getEncryptingCipher(masterSecret.getEncryptionKey());
- Mac mac = getMac(masterSecret.getMacKey());
-
- byte[] encryptedBody = getEncryptedBody(cipher, body);
- byte[] encryptedAndMacBody = getMacBody(mac, encryptedBody);
-
- return encryptedAndMacBody;
- } catch (GeneralSecurityException ge) {
- Log.w("bodycipher", ge);
- return null;
- }
-
- }
-
- public boolean verifyMacFor(String content, byte[] theirMac) {
- byte[] ourMac = getMacFor(content);
- Log.i(TAG, "Our Mac: " + Hex.toString(ourMac));
- Log.i(TAG, "Thr Mac: " + Hex.toString(theirMac));
- return Arrays.equals(ourMac, theirMac);
- }
-
- public byte[] getMacFor(String content) {
- Log.w(TAG, "Macing: " + content);
- try {
- Mac mac = getMac(masterSecret.getMacKey());
- return mac.doFinal(content.getBytes());
- } catch (GeneralSecurityException ike) {
- throw new AssertionError(ike);
- }
- }
-
- private byte[] decodeAndDecryptBytes(String body) throws InvalidMessageException {
- try {
- byte[] decodedBody = Base64.decode(body);
- return decryptBytes(decodedBody);
- } catch (IOException e) {
- throw new InvalidMessageException("Bad Base64 Encoding...", e);
- }
- }
-
- private String encryptAndEncodeBytes(@NonNull byte[] bytes) {
- byte[] encryptedAndMacBody = encryptBytes(bytes);
- return Base64.encodeBytes(encryptedAndMacBody);
- }
-
- private byte[] verifyMacBody(@NonNull Mac hmac, @NonNull byte[] encryptedAndMac) throws InvalidMessageException {
- if (encryptedAndMac.length < hmac.getMacLength()) {
- throw new InvalidMessageException("length(encrypted body + MAC) < length(MAC)");
- }
-
- byte[] encrypted = new byte[encryptedAndMac.length - hmac.getMacLength()];
- System.arraycopy(encryptedAndMac, 0, encrypted, 0, encrypted.length);
-
- byte[] remoteMac = new byte[hmac.getMacLength()];
- System.arraycopy(encryptedAndMac, encryptedAndMac.length - remoteMac.length, remoteMac, 0, remoteMac.length);
-
- byte[] localMac = hmac.doFinal(encrypted);
-
- if (!Arrays.equals(remoteMac, localMac))
- throw new InvalidMessageException("MAC doesen't match.");
-
- return encrypted;
- }
-
- private byte[] getDecryptedBody(Cipher cipher, byte[] encryptedBody) throws IllegalBlockSizeException, BadPaddingException {
- return cipher.doFinal(encryptedBody, cipher.getBlockSize(), encryptedBody.length - cipher.getBlockSize());
- }
-
- private byte[] getEncryptedBody(Cipher cipher, byte[] body) throws IllegalBlockSizeException, BadPaddingException {
- byte[] encrypted = cipher.doFinal(body);
- byte[] iv = cipher.getIV();
-
- byte[] ivAndBody = new byte[iv.length + encrypted.length];
- System.arraycopy(iv, 0, ivAndBody, 0, iv.length);
- System.arraycopy(encrypted, 0, ivAndBody, iv.length, encrypted.length);
-
- return ivAndBody;
- }
-
- private Mac getMac(SecretKeySpec key) throws NoSuchAlgorithmException, InvalidKeyException {
- // Mac hmac = Mac.getInstance("HmacSHA1");
- hmac.init(key);
-
- return hmac;
- }
-
- private byte[] getMacBody(Mac hmac, byte[] encryptedBody) {
- byte[] mac = hmac.doFinal(encryptedBody);
- byte[] encryptedAndMac = new byte[encryptedBody.length + mac.length];
-
- System.arraycopy(encryptedBody, 0, encryptedAndMac, 0, encryptedBody.length);
- System.arraycopy(mac, 0, encryptedAndMac, encryptedBody.length, mac.length);
-
- return encryptedAndMac;
- }
-
- private Cipher getDecryptingCipher(SecretKeySpec key, byte[] encryptedBody) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException {
- // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- IvParameterSpec iv = new IvParameterSpec(encryptedBody, 0, decryptingCipher.getBlockSize());
- decryptingCipher.init(Cipher.DECRYPT_MODE, key, iv);
-
- return decryptingCipher;
- }
-
- private Cipher getEncryptingCipher(SecretKeySpec key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException {
- // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- encryptingCipher.init(Cipher.ENCRYPT_MODE, key);
-
- return encryptingCipher;
- }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecret.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecret.java
deleted file mode 100644
index e849aae617..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecret.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.crypto;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import javax.crypto.spec.SecretKeySpec;
-import java.util.Arrays;
-
-/**
- * When a user first initializes TextSecure, a few secrets
- * are generated. These are:
- *
- * 1) A 128bit symmetric encryption key.
- * 2) A 160bit symmetric MAC key.
- * 3) An ECC keypair.
- *
- * The first two, along with the ECC keypair's private key, are
- * then encrypted on disk using PBE.
- *
- * This class represents 1 and 2.
- *
- * @author Moxie Marlinspike
- */
-
-public class MasterSecret implements Parcelable {
-
- private final SecretKeySpec encryptionKey;
- private final SecretKeySpec macKey;
-
- public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
- @Override
- public MasterSecret createFromParcel(Parcel in) {
- return new MasterSecret(in);
- }
-
- @Override
- public MasterSecret[] newArray(int size) {
- return new MasterSecret[size];
- }
- };
-
- public MasterSecret(SecretKeySpec encryptionKey, SecretKeySpec macKey) {
- this.encryptionKey = encryptionKey;
- this.macKey = macKey;
- }
-
- private MasterSecret(Parcel in) {
- byte[] encryptionKeyBytes = new byte[in.readInt()];
- in.readByteArray(encryptionKeyBytes);
-
- byte[] macKeyBytes = new byte[in.readInt()];
- in.readByteArray(macKeyBytes);
-
- this.encryptionKey = new SecretKeySpec(encryptionKeyBytes, "AES");
- this.macKey = new SecretKeySpec(macKeyBytes, "HmacSHA1");
-
- // SecretKeySpec does an internal copy in its constructor.
- Arrays.fill(encryptionKeyBytes, (byte) 0x00);
- Arrays.fill(macKeyBytes, (byte)0x00);
- }
-
-
- public SecretKeySpec getEncryptionKey() {
- return this.encryptionKey;
- }
-
- public SecretKeySpec getMacKey() {
- return this.macKey;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(encryptionKey.getEncoded().length);
- out.writeByteArray(encryptionKey.getEncoded());
- out.writeInt(macKey.getEncoded().length);
- out.writeByteArray(macKey.getEncoded());
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- public MasterSecret parcelClone() {
- Parcel thisParcel = Parcel.obtain();
- Parcel thatParcel = Parcel.obtain();
- byte[] bytes = null;
-
- thisParcel.writeValue(this);
- bytes = thisParcel.marshall();
-
- thatParcel.unmarshall(bytes, 0, bytes.length);
- thatParcel.setDataPosition(0);
-
- MasterSecret that = (MasterSecret)thatParcel.readValue(MasterSecret.class.getClassLoader());
-
- thisParcel.recycle();
- thatParcel.recycle();
-
- return that;
- }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java
deleted file mode 100644
index 1797941ff1..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- * Copyright (C) 2013 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package org.thoughtcrime.securesms.crypto;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import android.text.TextUtils;
-import org.thoughtcrime.securesms.logging.Log;
-
-import org.thoughtcrime.securesms.util.Base64;
-import org.thoughtcrime.securesms.util.Util;
-import org.session.libsignal.libsignal.InvalidKeyException;
-import org.session.libsignal.libsignal.ecc.Curve;
-import org.session.libsignal.libsignal.ecc.ECKeyPair;
-import org.session.libsignal.libsignal.ecc.ECPrivateKey;
-import org.session.libsignal.libsignal.ecc.ECPublicKey;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-import javax.crypto.spec.PBEParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * Helper class for generating and securely storing a MasterSecret.
- *
- * @author Moxie Marlinspike
- */
-
-public class MasterSecretUtil {
-
- public static final String UNENCRYPTED_PASSPHRASE = "unencrypted";
- public static final String PREFERENCES_NAME = "SecureSMS-Preferences";
-
- private static final String ASYMMETRIC_LOCAL_PUBLIC_DJB = "asymmetric_master_secret_curve25519_public";
- private static final String ASYMMETRIC_LOCAL_PRIVATE_DJB = "asymmetric_master_secret_curve25519_private";
-
- public static MasterSecret changeMasterSecretPassphrase(Context context,
- MasterSecret masterSecret,
- String newPassphrase)
- {
- try {
- byte[] combinedSecrets = Util.combine(masterSecret.getEncryptionKey().getEncoded(),
- masterSecret.getMacKey().getEncoded());
-
- byte[] encryptionSalt = generateSalt();
- int iterations = generateIterationCount(newPassphrase, encryptionSalt);
- byte[] encryptedMasterSecret = encryptWithPassphrase(encryptionSalt, iterations, combinedSecrets, newPassphrase);
- byte[] macSalt = generateSalt();
- byte[] encryptedAndMacdMasterSecret = macWithPassphrase(macSalt, iterations, encryptedMasterSecret, newPassphrase);
-
- save(context, "encryption_salt", encryptionSalt);
- save(context, "mac_salt", macSalt);
- save(context, "passphrase_iterations", iterations);
- save(context, "master_secret", encryptedAndMacdMasterSecret);
- save(context, "passphrase_initialized", true);
-
- return masterSecret;
- } catch (GeneralSecurityException gse) {
- throw new AssertionError(gse);
- }
- }
-
- public static MasterSecret changeMasterSecretPassphrase(Context context,
- String originalPassphrase,
- String newPassphrase)
- throws InvalidPassphraseException
- {
- MasterSecret masterSecret = getMasterSecret(context, originalPassphrase);
- changeMasterSecretPassphrase(context, masterSecret, newPassphrase);
-
- return masterSecret;
- }
-
- public static MasterSecret getMasterSecret(Context context, String passphrase)
- throws InvalidPassphraseException
- {
- try {
- byte[] encryptedAndMacdMasterSecret = retrieve(context, "master_secret");
- byte[] macSalt = retrieve(context, "mac_salt");
- int iterations = retrieve(context, "passphrase_iterations", 100);
- byte[] encryptedMasterSecret = verifyMac(macSalt, iterations, encryptedAndMacdMasterSecret, passphrase);
- byte[] encryptionSalt = retrieve(context, "encryption_salt");
- byte[] combinedSecrets = decryptWithPassphrase(encryptionSalt, iterations, encryptedMasterSecret, passphrase);
- byte[] encryptionSecret = Util.split(combinedSecrets, 16, 20)[0];
- byte[] macSecret = Util.split(combinedSecrets, 16, 20)[1];
-
- return new MasterSecret(new SecretKeySpec(encryptionSecret, "AES"),
- new SecretKeySpec(macSecret, "HmacSHA1"));
- } catch (GeneralSecurityException e) {
- Log.w("keyutil", e);
- return null; //XXX
- } catch (IOException e) {
- Log.w("keyutil", e);
- return null; //XXX
- }
- }
-
- public static AsymmetricMasterSecret getAsymmetricMasterSecret(@NonNull Context context,
- @Nullable MasterSecret masterSecret)
- {
- try {
- byte[] djbPublicBytes = retrieve(context, ASYMMETRIC_LOCAL_PUBLIC_DJB);
- byte[] djbPrivateBytes = retrieve(context, ASYMMETRIC_LOCAL_PRIVATE_DJB);
-
- ECPublicKey djbPublicKey = null;
- ECPrivateKey djbPrivateKey = null;
-
- if (djbPublicBytes != null) {
- djbPublicKey = Curve.decodePoint(djbPublicBytes, 0);
- }
-
- if (masterSecret != null) {
- MasterCipher masterCipher = new MasterCipher(masterSecret);
-
- if (djbPrivateBytes != null) {
- djbPrivateKey = masterCipher.decryptKey(djbPrivateBytes);
- }
- }
-
- return new AsymmetricMasterSecret(djbPublicKey, djbPrivateKey);
- } catch (InvalidKeyException | IOException ike) {
- throw new AssertionError(ike);
- }
- }
-
- public static AsymmetricMasterSecret generateAsymmetricMasterSecret(Context context,
- MasterSecret masterSecret)
- {
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- ECKeyPair keyPair = Curve.generateKeyPair();
-
- save(context, ASYMMETRIC_LOCAL_PUBLIC_DJB, keyPair.getPublicKey().serialize());
- save(context, ASYMMETRIC_LOCAL_PRIVATE_DJB, masterCipher.encryptKey(keyPair.getPrivateKey()));
-
- return new AsymmetricMasterSecret(keyPair.getPublicKey(), keyPair.getPrivateKey());
- }
-
- public static MasterSecret generateMasterSecret(Context context, String passphrase) {
- try {
- byte[] encryptionSecret = generateEncryptionSecret();
- byte[] macSecret = generateMacSecret();
- byte[] masterSecret = Util.combine(encryptionSecret, macSecret);
- byte[] encryptionSalt = generateSalt();
- int iterations = generateIterationCount(passphrase, encryptionSalt);
- byte[] encryptedMasterSecret = encryptWithPassphrase(encryptionSalt, iterations, masterSecret, passphrase);
- byte[] macSalt = generateSalt();
- byte[] encryptedAndMacdMasterSecret = macWithPassphrase(macSalt, iterations, encryptedMasterSecret, passphrase);
-
- save(context, "encryption_salt", encryptionSalt);
- save(context, "mac_salt", macSalt);
- save(context, "passphrase_iterations", iterations);
- save(context, "master_secret", encryptedAndMacdMasterSecret);
- save(context, "passphrase_initialized", true);
-
- return new MasterSecret(new SecretKeySpec(encryptionSecret, "AES"),
- new SecretKeySpec(macSecret, "HmacSHA1"));
- } catch (GeneralSecurityException e) {
- Log.w("keyutil", e);
- return null;
- }
- }
-
- public static boolean hasAsymmericMasterSecret(Context context) {
- SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, 0);
- return settings.contains(ASYMMETRIC_LOCAL_PUBLIC_DJB);
- }
-
- public static boolean isPassphraseInitialized(Context context) {
- SharedPreferences preferences = context.getSharedPreferences(PREFERENCES_NAME, 0);
- return preferences.getBoolean("passphrase_initialized", false);
- }
-
- public static void clear(Context context) {
- context.getSharedPreferences(PREFERENCES_NAME, 0).edit().clear().commit();
- }
-
- private static void save(Context context, String key, int value) {
- if (!context.getSharedPreferences(PREFERENCES_NAME, 0)
- .edit()
- .putInt(key, value)
- .commit())
- {
- throw new AssertionError("failed to save a shared pref in MasterSecretUtil");
- }
- }
-
- private static void save(Context context, String key, byte[] value) {
- if (!context.getSharedPreferences(PREFERENCES_NAME, 0)
- .edit()
- .putString(key, Base64.encodeBytes(value))
- .commit())
- {
- throw new AssertionError("failed to save a shared pref in MasterSecretUtil");
- }
- }
-
- private static void save(Context context, String key, boolean value) {
- if (!context.getSharedPreferences(PREFERENCES_NAME, 0)
- .edit()
- .putBoolean(key, value)
- .commit())
- {
- throw new AssertionError("failed to save a shared pref in MasterSecretUtil");
- }
- }
-
- private static byte[] retrieve(Context context, String key) throws IOException {
- SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, 0);
- String encodedValue = settings.getString(key, "");
-
- if (TextUtils.isEmpty(encodedValue)) return null;
- else return Base64.decode(encodedValue);
- }
-
- private static int retrieve(Context context, String key, int defaultValue) throws IOException {
- SharedPreferences settings = context.getSharedPreferences(PREFERENCES_NAME, 0);
- return settings.getInt(key, defaultValue);
- }
-
- private static byte[] generateEncryptionSecret() {
- try {
- KeyGenerator generator = KeyGenerator.getInstance("AES");
- generator.init(128);
-
- SecretKey key = generator.generateKey();
- return key.getEncoded();
- } catch (NoSuchAlgorithmException ex) {
- Log.w("keyutil", ex);
- return null;
- }
- }
-
- private static byte[] generateMacSecret() {
- try {
- KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
- return generator.generateKey().getEncoded();
- } catch (NoSuchAlgorithmException e) {
- Log.w("keyutil", e);
- return null;
- }
- }
-
- private static byte[] generateSalt() {
- SecureRandom random = new SecureRandom();
- byte[] salt = new byte[16];
- random.nextBytes(salt);
-
- return salt;
- }
-
- private static int generateIterationCount(String passphrase, byte[] salt) {
- int TARGET_ITERATION_TIME = 50; //ms
- int MINIMUM_ITERATION_COUNT = 100; //default for low-end devices
- int BENCHMARK_ITERATION_COUNT = 10000; //baseline starting iteration count
-
- try {
- PBEKeySpec keyspec = new PBEKeySpec(passphrase.toCharArray(), salt, BENCHMARK_ITERATION_COUNT);
- SecretKeyFactory skf = SecretKeyFactory.getInstance("PBEWITHSHA1AND128BITAES-CBC-BC");
-
- long startTime = System.currentTimeMillis();
- skf.generateSecret(keyspec);
- long finishTime = System.currentTimeMillis();
-
- int scaledIterationTarget = (int) (((double)BENCHMARK_ITERATION_COUNT / (double)(finishTime - startTime)) * TARGET_ITERATION_TIME);
-
- if (scaledIterationTarget < MINIMUM_ITERATION_COUNT) return MINIMUM_ITERATION_COUNT;
- else return scaledIterationTarget;
- } catch (NoSuchAlgorithmException e) {
- Log.w("MasterSecretUtil", e);
- return MINIMUM_ITERATION_COUNT;
- } catch (InvalidKeySpecException e) {
- Log.w("MasterSecretUtil", e);
- return MINIMUM_ITERATION_COUNT;
- }
- }
-
- private static SecretKey getKeyFromPassphrase(String passphrase, byte[] salt, int iterations)
- throws GeneralSecurityException
- {
- PBEKeySpec keyspec = new PBEKeySpec(passphrase.toCharArray(), salt, iterations);
- SecretKeyFactory skf = SecretKeyFactory.getInstance("PBEWITHSHA1AND128BITAES-CBC-BC");
- return skf.generateSecret(keyspec);
- }
-
- private static Cipher getCipherFromPassphrase(String passphrase, byte[] salt, int iterations, int opMode)
- throws GeneralSecurityException
- {
- SecretKey key = getKeyFromPassphrase(passphrase, salt, iterations);
- Cipher cipher = Cipher.getInstance(key.getAlgorithm());
- cipher.init(opMode, key, new PBEParameterSpec(salt, iterations));
-
- return cipher;
- }
-
- private static byte[] encryptWithPassphrase(byte[] encryptionSalt, int iterations, byte[] data, String passphrase)
- throws GeneralSecurityException
- {
- Cipher cipher = getCipherFromPassphrase(passphrase, encryptionSalt, iterations, Cipher.ENCRYPT_MODE);
- return cipher.doFinal(data);
- }
-
- private static byte[] decryptWithPassphrase(byte[] encryptionSalt, int iterations, byte[] data, String passphrase)
- throws GeneralSecurityException, IOException
- {
- Cipher cipher = getCipherFromPassphrase(passphrase, encryptionSalt, iterations, Cipher.DECRYPT_MODE);
- return cipher.doFinal(data);
- }
-
- private static Mac getMacForPassphrase(String passphrase, byte[] salt, int iterations)
- throws GeneralSecurityException
- {
- SecretKey key = getKeyFromPassphrase(passphrase, salt, iterations);
- byte[] pbkdf2 = key.getEncoded();
- SecretKeySpec hmacKey = new SecretKeySpec(pbkdf2, "HmacSHA1");
- Mac hmac = Mac.getInstance("HmacSHA1");
- hmac.init(hmacKey);
-
- return hmac;
- }
-
- private static byte[] verifyMac(byte[] macSalt, int iterations, byte[] encryptedAndMacdData, String passphrase) throws InvalidPassphraseException, GeneralSecurityException, IOException {
- Mac hmac = getMacForPassphrase(passphrase, macSalt, iterations);
-
- byte[] encryptedData = new byte[encryptedAndMacdData.length - hmac.getMacLength()];
- System.arraycopy(encryptedAndMacdData, 0, encryptedData, 0, encryptedData.length);
-
- byte[] givenMac = new byte[hmac.getMacLength()];
- System.arraycopy(encryptedAndMacdData, encryptedAndMacdData.length-hmac.getMacLength(), givenMac, 0, givenMac.length);
-
- byte[] localMac = hmac.doFinal(encryptedData);
-
- if (Arrays.equals(givenMac, localMac)) return encryptedData;
- else throw new InvalidPassphraseException("MAC Error");
- }
-
- private static byte[] macWithPassphrase(byte[] macSalt, int iterations, byte[] data, String passphrase) throws GeneralSecurityException {
- Mac hmac = getMacForPassphrase(passphrase, macSalt, iterations);
- byte[] mac = hmac.doFinal(data);
- byte[] result = new byte[data.length + mac.length];
-
- System.arraycopy(data, 0, result, 0, data.length);
- System.arraycopy(mac, 0, result, data.length, mac.length);
-
- return result;
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
index f02e1d9c05..7289cc3d5d 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java
@@ -17,18 +17,15 @@
package org.thoughtcrime.securesms.database;
import android.content.Context;
+
import androidx.annotation.NonNull;
import net.sqlcipher.database.SQLiteDatabase;
-import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
import org.thoughtcrime.securesms.crypto.AttachmentSecret;
import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
import org.thoughtcrime.securesms.crypto.DatabaseSecretProvider;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.database.helpers.ClassicOpenHelper;
-import org.thoughtcrime.securesms.database.helpers.SQLCipherMigrationHelper;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase;
import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase;
@@ -36,7 +33,6 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.database.SharedSenderKeysDatabase;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
public class DatabaseFactory {
@@ -227,28 +223,4 @@ public class DatabaseFactory {
this.sskDatabase = new SharedSenderKeysDatabase(context, databaseHelper);
}
- public void onApplicationLevelUpgrade(@NonNull Context context, @NonNull MasterSecret masterSecret,
- int fromVersion, DatabaseUpgradeActivity.DatabaseUpgradeListener listener)
- {
- databaseHelper.getWritableDatabase();
-
- ClassicOpenHelper legacyOpenHelper = null;
-
- if (fromVersion < DatabaseUpgradeActivity.ASYMMETRIC_MASTER_SECRET_FIX_VERSION) {
- legacyOpenHelper = new ClassicOpenHelper(context);
- legacyOpenHelper.onApplicationLevelUpgrade(context, masterSecret, fromVersion, listener);
- }
-
- if (fromVersion < DatabaseUpgradeActivity.SQLCIPHER && TextSecurePreferences.getNeedsSqlCipherMigration(context)) {
- if (legacyOpenHelper == null) {
- legacyOpenHelper = new ClassicOpenHelper(context);
- }
-
- SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret,
- legacyOpenHelper.getWritableDatabase(),
- databaseHelper.getWritableDatabase(),
- listener);
- }
- }
-
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java
deleted file mode 100644
index 1ad2418169..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java
+++ /dev/null
@@ -1,1448 +0,0 @@
-package org.thoughtcrime.securesms.database.helpers;
-
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteConstraintException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import androidx.annotation.Nullable;
-import android.text.TextUtils;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-import org.thoughtcrime.securesms.ApplicationContext;
-import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
-import org.thoughtcrime.securesms.crypto.AttachmentSecret;
-import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream;
-import org.thoughtcrime.securesms.crypto.MasterCipher;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.database.AttachmentDatabase;
-import org.thoughtcrime.securesms.database.DraftDatabase;
-import org.thoughtcrime.securesms.database.GroupDatabase;
-import org.thoughtcrime.securesms.database.GroupReceiptDatabase;
-import org.thoughtcrime.securesms.database.MmsDatabase;
-import org.thoughtcrime.securesms.database.PushDatabase;
-import org.thoughtcrime.securesms.database.RecipientDatabase;
-import org.thoughtcrime.securesms.database.SmsDatabase;
-import org.thoughtcrime.securesms.database.ThreadDatabase;
-import org.thoughtcrime.securesms.logging.Log;
-import org.thoughtcrime.securesms.util.Base64;
-import org.thoughtcrime.securesms.util.DelimiterUtil;
-import org.thoughtcrime.securesms.util.Hex;
-import org.thoughtcrime.securesms.util.JsonUtils;
-import org.thoughtcrime.securesms.util.MediaUtil;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-import org.thoughtcrime.securesms.util.Util;
-import org.session.libsignal.libsignal.IdentityKey;
-import org.session.libsignal.libsignal.InvalidMessageException;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.SecureRandom;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-public class ClassicOpenHelper extends SQLiteOpenHelper {
-
- static final String NAME = "messages.db";
-
- private static final int INTRODUCED_IDENTITIES_VERSION = 2;
- private static final int INTRODUCED_INDEXES_VERSION = 3;
- private static final int INTRODUCED_DATE_SENT_VERSION = 4;
- private static final int INTRODUCED_DRAFTS_VERSION = 5;
- private static final int INTRODUCED_NEW_TYPES_VERSION = 6;
- private static final int INTRODUCED_MMS_BODY_VERSION = 7;
- private static final int INTRODUCED_MMS_FROM_VERSION = 8;
- private static final int INTRODUCED_TOFU_IDENTITY_VERSION = 9;
- private static final int INTRODUCED_PUSH_DATABASE_VERSION = 10;
- private static final int INTRODUCED_GROUP_DATABASE_VERSION = 11;
- private static final int INTRODUCED_PUSH_FIX_VERSION = 12;
- private static final int INTRODUCED_DELIVERY_RECEIPTS = 13;
- private static final int INTRODUCED_PART_DATA_SIZE_VERSION = 14;
- private static final int INTRODUCED_THUMBNAILS_VERSION = 15;
- private static final int INTRODUCED_IDENTITY_COLUMN_VERSION = 16;
- private static final int INTRODUCED_UNIQUE_PART_IDS_VERSION = 17;
- private static final int INTRODUCED_RECIPIENT_PREFS_DB = 18;
- private static final int INTRODUCED_ENVELOPE_CONTENT_VERSION = 19;
- private static final int INTRODUCED_COLOR_PREFERENCE_VERSION = 20;
- private static final int INTRODUCED_DB_OPTIMIZATIONS_VERSION = 21;
- private static final int INTRODUCED_INVITE_REMINDERS_VERSION = 22;
- private static final int INTRODUCED_CONVERSATION_LIST_THUMBNAILS_VERSION = 23;
- private static final int INTRODUCED_ARCHIVE_VERSION = 24;
- private static final int INTRODUCED_CONVERSATION_LIST_STATUS_VERSION = 25;
- private static final int MIGRATED_CONVERSATION_LIST_STATUS_VERSION = 26;
- private static final int INTRODUCED_SUBSCRIPTION_ID_VERSION = 27;
- private static final int INTRODUCED_EXPIRE_MESSAGES_VERSION = 28;
- private static final int INTRODUCED_LAST_SEEN = 29;
- private static final int INTRODUCED_DIGEST = 30;
- private static final int INTRODUCED_NOTIFIED = 31;
- private static final int INTRODUCED_DOCUMENTS = 32;
- private static final int INTRODUCED_FAST_PREFLIGHT = 33;
- private static final int INTRODUCED_VOICE_NOTES = 34;
- private static final int INTRODUCED_IDENTITY_TIMESTAMP = 35;
- private static final int SANIFY_ATTACHMENT_DOWNLOAD = 36;
- private static final int NO_MORE_CANONICAL_ADDRESS_DATABASE = 37;
- private static final int NO_MORE_RECIPIENTS_PLURAL = 38;
- private static final int INTERNAL_DIRECTORY = 39;
- private static final int INTERNAL_SYSTEM_DISPLAY_NAME = 40;
- private static final int PROFILES = 41;
- private static final int PROFILE_SHARING_APPROVAL = 42;
- private static final int UNSEEN_NUMBER_OFFER = 43;
- private static final int READ_RECEIPTS = 44;
- private static final int GROUP_RECEIPT_TRACKING = 45;
- private static final int UNREAD_COUNT_VERSION = 46;
- private static final int MORE_RECIPIENT_FIELDS = 47;
- private static final int DATABASE_VERSION = 47;
-
- private static final String TAG = ClassicOpenHelper.class.getSimpleName();
-
- private final Context context;
-
- public ClassicOpenHelper(Context context) {
- super(context, NAME, null, DATABASE_VERSION);
- this.context = context.getApplicationContext();
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(SmsDatabase.CREATE_TABLE);
- db.execSQL(MmsDatabase.CREATE_TABLE);
- db.execSQL(AttachmentDatabase.CREATE_TABLE);
- db.execSQL(ThreadDatabase.CREATE_TABLE);
- db.execSQL(DraftDatabase.CREATE_TABLE);
- db.execSQL(PushDatabase.CREATE_TABLE);
- db.execSQL(GroupDatabase.CREATE_TABLE);
- db.execSQL(RecipientDatabase.CREATE_TABLE);
- db.execSQL(GroupReceiptDatabase.CREATE_TABLE);
-
- executeStatements(db, SmsDatabase.CREATE_INDEXS);
- executeStatements(db, MmsDatabase.CREATE_INDEXS);
- executeStatements(db, AttachmentDatabase.CREATE_INDEXS);
- executeStatements(db, ThreadDatabase.CREATE_INDEXS);
- executeStatements(db, DraftDatabase.CREATE_INDEXS);
- executeStatements(db, GroupDatabase.CREATE_INDEXS);
- executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES);
- }
-
- public void onApplicationLevelUpgrade(Context context, MasterSecret masterSecret, int fromVersion,
- DatabaseUpgradeActivity.DatabaseUpgradeListener listener)
- {
- SQLiteDatabase db = getWritableDatabase();
- db.beginTransaction();
-
- if (fromVersion < DatabaseUpgradeActivity.NO_MORE_KEY_EXCHANGE_PREFIX_VERSION) {
- String KEY_EXCHANGE = "?TextSecureKeyExchange";
- String PROCESSED_KEY_EXCHANGE = "?TextSecureKeyExchangd";
- String STALE_KEY_EXCHANGE = "?TextSecureKeyExchangs";
- int ROW_LIMIT = 500;
-
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- int smsCount = 0;
- int threadCount = 0;
- int skip = 0;
-
- Cursor cursor = db.query("sms", new String[] {"COUNT(*)"}, "type & " + 0x80000000 + " != 0",
- null, null, null, null);
-
- if (cursor != null && cursor.moveToFirst()) {
- smsCount = cursor.getInt(0);
- cursor.close();
- }
-
- cursor = db.query("thread", new String[] {"COUNT(*)"}, "snippet_type & " + 0x80000000 + " != 0",
- null, null, null, null);
-
- if (cursor != null && cursor.moveToFirst()) {
- threadCount = cursor.getInt(0);
- cursor.close();
- }
-
- Cursor smsCursor = null;
-
- Log.i("DatabaseFactory", "Upgrade count: " + (smsCount + threadCount));
-
- do {
- Log.i("DatabaseFactory", "Looping SMS cursor...");
- if (smsCursor != null)
- smsCursor.close();
-
- smsCursor = db.query("sms", new String[] {"_id", "type", "body"},
- "type & " + 0x80000000 + " != 0",
- null, null, null, "_id", skip + "," + ROW_LIMIT);
-
- while (smsCursor != null && smsCursor.moveToNext()) {
- listener.setProgress(smsCursor.getPosition() + skip, smsCount + threadCount);
-
- try {
- String body = masterCipher.decryptBody(smsCursor.getString(smsCursor.getColumnIndexOrThrow("body")));
- long type = smsCursor.getLong(smsCursor.getColumnIndexOrThrow("type"));
- long id = smsCursor.getLong(smsCursor.getColumnIndexOrThrow("_id"));
-
- if (body.startsWith(KEY_EXCHANGE)) {
- body = body.substring(KEY_EXCHANGE.length());
- body = masterCipher.encryptBody(body);
- type |= 0x8000;
-
- db.execSQL("UPDATE sms SET body = ?, type = ? WHERE _id = ?",
- new String[] {body, type+"", id+""});
- } else if (body.startsWith(PROCESSED_KEY_EXCHANGE)) {
- body = body.substring(PROCESSED_KEY_EXCHANGE.length());
- body = masterCipher.encryptBody(body);
- type |= (0x8000 | 0x2000);
-
- db.execSQL("UPDATE sms SET body = ?, type = ? WHERE _id = ?",
- new String[] {body, type+"", id+""});
- } else if (body.startsWith(STALE_KEY_EXCHANGE)) {
- body = body.substring(STALE_KEY_EXCHANGE.length());
- body = masterCipher.encryptBody(body);
- type |= (0x8000 | 0x4000);
-
- db.execSQL("UPDATE sms SET body = ?, type = ? WHERE _id = ?",
- new String[] {body, type+"", id+""});
- }
- } catch (InvalidMessageException e) {
- Log.w("DatabaseFactory", e);
- }
- }
-
- skip += ROW_LIMIT;
- } while (smsCursor != null && smsCursor.getCount() > 0);
-
-
-
- Cursor threadCursor = null;
- skip = 0;
-
- do {
- Log.i("DatabaseFactory", "Looping thread cursor...");
-
- if (threadCursor != null)
- threadCursor.close();
-
- threadCursor = db.query("thread", new String[] {"_id", "snippet_type", "snippet"},
- "snippet_type & " + 0x80000000 + " != 0",
- null, null, null, "_id", skip + "," + ROW_LIMIT);
-
- while (threadCursor != null && threadCursor.moveToNext()) {
- listener.setProgress(smsCount + threadCursor.getPosition(), smsCount + threadCount);
-
- try {
- String snippet = threadCursor.getString(threadCursor.getColumnIndexOrThrow("snippet"));
- long snippetType = threadCursor.getLong(threadCursor.getColumnIndexOrThrow("snippet_type"));
- long id = threadCursor.getLong(threadCursor.getColumnIndexOrThrow("_id"));
-
- if (!TextUtils.isEmpty(snippet)) {
- snippet = masterCipher.decryptBody(snippet);
- }
-
- if (snippet.startsWith(KEY_EXCHANGE)) {
- snippet = snippet.substring(KEY_EXCHANGE.length());
- snippet = masterCipher.encryptBody(snippet);
- snippetType |= 0x8000;
-
- db.execSQL("UPDATE thread SET snippet = ?, snippet_type = ? WHERE _id = ?",
- new String[] {snippet, snippetType+"", id+""});
- } else if (snippet.startsWith(PROCESSED_KEY_EXCHANGE)) {
- snippet = snippet.substring(PROCESSED_KEY_EXCHANGE.length());
- snippet = masterCipher.encryptBody(snippet);
- snippetType |= (0x8000 | 0x2000);
-
- db.execSQL("UPDATE thread SET snippet = ?, snippet_type = ? WHERE _id = ?",
- new String[] {snippet, snippetType+"", id+""});
- } else if (snippet.startsWith(STALE_KEY_EXCHANGE)) {
- snippet = snippet.substring(STALE_KEY_EXCHANGE.length());
- snippet = masterCipher.encryptBody(snippet);
- snippetType |= (0x8000 | 0x4000);
-
- db.execSQL("UPDATE thread SET snippet = ?, snippet_type = ? WHERE _id = ?",
- new String[] {snippet, snippetType+"", id+""});
- }
- } catch (InvalidMessageException e) {
- Log.w("DatabaseFactory", e);
- }
- }
-
- skip += ROW_LIMIT;
- } while (threadCursor != null && threadCursor.getCount() > 0);
-
- if (smsCursor != null)
- smsCursor.close();
-
- if (threadCursor != null)
- threadCursor.close();
- }
-
- if (fromVersion < DatabaseUpgradeActivity.MMS_BODY_VERSION) {
- Log.i("DatabaseFactory", "Update MMS bodies...");
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- Cursor mmsCursor = db.query("mms", new String[] {"_id"},
- "msg_box & " + 0x80000000L + " != 0",
- null, null, null, null);
-
- Log.i("DatabaseFactory", "Got MMS rows: " + (mmsCursor == null ? "null" : mmsCursor.getCount()));
-
- while (mmsCursor != null && mmsCursor.moveToNext()) {
- listener.setProgress(mmsCursor.getPosition(), mmsCursor.getCount());
-
- long mmsId = mmsCursor.getLong(mmsCursor.getColumnIndexOrThrow("_id"));
- String body = null;
- int partCount = 0;
- Cursor partCursor = db.query("part", new String[] {"_id", "ct", "_data", "encrypted"},
- "mid = ?", new String[] {mmsId+""}, null, null, null);
-
- while (partCursor != null && partCursor.moveToNext()) {
- String contentType = partCursor.getString(partCursor.getColumnIndexOrThrow("ct"));
-
- if (MediaUtil.isTextType(contentType)) {
- try {
- long partId = partCursor.getLong(partCursor.getColumnIndexOrThrow("_id"));
- String dataLocation = partCursor.getString(partCursor.getColumnIndexOrThrow("_data"));
- boolean encrypted = partCursor.getInt(partCursor.getColumnIndexOrThrow("encrypted")) == 1;
- File dataFile = new File(dataLocation);
-
- InputStream is;
-
- AttachmentSecret attachmentSecret = new AttachmentSecret(masterSecret.getEncryptionKey().getEncoded(),
- masterSecret.getMacKey().getEncoded(), null);
- if (encrypted) is = ClassicDecryptingPartInputStream.createFor(attachmentSecret, dataFile);
- else is = new FileInputStream(dataFile);
-
- body = (body == null) ? Util.readFullyAsString(is) : body + " " + Util.readFullyAsString(is);
-
- //noinspection ResultOfMethodCallIgnored
- dataFile.delete();
- db.delete("part", "_id = ?", new String[] {partId+""});
- } catch (IOException e) {
- Log.w("DatabaseFactory", e);
- }
- } else if (MediaUtil.isAudioType(contentType) ||
- MediaUtil.isImageType(contentType) ||
- MediaUtil.isVideoType(contentType))
- {
- partCount++;
- }
- }
-
- if (!TextUtils.isEmpty(body)) {
- body = masterCipher.encryptBody(body);
- db.execSQL("UPDATE mms SET body = ?, part_count = ? WHERE _id = ?",
- new String[] {body, partCount+"", mmsId+""});
- } else {
- db.execSQL("UPDATE mms SET part_count = ? WHERE _id = ?",
- new String[] {partCount+"", mmsId+""});
- }
-
- Log.i("DatabaseFactory", "Updated body: " + body + " and part_count: " + partCount);
- }
- }
-
- if (fromVersion < DatabaseUpgradeActivity.TOFU_IDENTITIES_VERSION) {
- File sessionDirectory = new File(context.getFilesDir() + File.separator + "sessions");
-
- if (sessionDirectory.exists() && sessionDirectory.isDirectory()) {
- File[] sessions = sessionDirectory.listFiles();
-
- if (sessions != null) {
- for (File session : sessions) {
- String name = session.getName();
-
- if (name.matches("[0-9]+")) {
- long recipientId = Long.parseLong(name);
- IdentityKey identityKey = null;
- // NOTE (4/21/14) -- At this moment in time, we're forgetting the ability to parse
- // V1 session records. Despite our usual attempts to avoid using shared code in the
- // upgrade path, this is too complex to put here directly. Thus, unfortunately
- // this operation is now lost to the ages. From the git log, it seems to have been
- // almost exactly a year since this went in, so hopefully the bulk of people have
- // already upgraded.
-// IdentityKey identityKey = Session.getRemoteIdentityKey(context, masterSecret, recipientId);
-
- if (identityKey != null) {
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- String identityKeyString = Base64.encodeBytes(identityKey.serialize());
- String macString = Base64.encodeBytes(masterCipher.getMacFor(recipientId +
- identityKeyString));
-
- db.execSQL("REPLACE INTO identities (recipient, key, mac) VALUES (?, ?, ?)",
- new String[] {recipientId+"", identityKeyString, macString});
- }
- }
- }
- }
- }
- }
-
- if (fromVersion < DatabaseUpgradeActivity.ASYMMETRIC_MASTER_SECRET_FIX_VERSION) {
- if (!MasterSecretUtil.hasAsymmericMasterSecret(context)) {
- MasterSecretUtil.generateAsymmetricMasterSecret(context, masterSecret);
-
- MasterCipher masterCipher = new MasterCipher(masterSecret);
- Cursor cursor = null;
-
- try {
- cursor = db.query(SmsDatabase.TABLE_NAME,
- new String[] {SmsDatabase.ID, SmsDatabase.BODY, SmsDatabase.TYPE},
- SmsDatabase.TYPE + " & ? == 0",
- new String[] {String.valueOf(SmsDatabase.Types.ENCRYPTION_MASK)},
- null, null, null);
-
- while (cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String body = cursor.getString(1);
- long type = cursor.getLong(2);
-
- String encryptedBody = masterCipher.encryptBody(body);
-
- ContentValues update = new ContentValues();
- update.put(SmsDatabase.BODY, encryptedBody);
- update.put(SmsDatabase.TYPE, type | 0x80000000); // Inline now deprecated symmetric encryption type
-
- db.update(SmsDatabase.TABLE_NAME, update, SmsDatabase.ID + " = ?",
- new String[] {String.valueOf(id)});
- }
- } finally {
- if (cursor != null)
- cursor.close();
- }
- }
- }
-
- db.setTransactionSuccessful();
- db.endTransaction();
-
-// DecryptingQueue.schedulePendingDecrypts(context, masterSecret);
- ApplicationContext.getInstance(context).messageNotifier.updateNotification(context);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- db.beginTransaction();
-
- if (oldVersion < INTRODUCED_IDENTITIES_VERSION) {
- db.execSQL("CREATE TABLE identities (_id INTEGER PRIMARY KEY, key TEXT UNIQUE, name TEXT UNIQUE, mac TEXT);");
- }
-
- if (oldVersion < INTRODUCED_INDEXES_VERSION) {
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS sms_thread_id_index ON sms (thread_id);",
- "CREATE INDEX IF NOT EXISTS sms_read_index ON sms (read);",
- "CREATE INDEX IF NOT EXISTS sms_read_and_thread_id_index ON sms (read,thread_id);",
- "CREATE INDEX IF NOT EXISTS sms_type_index ON sms (type);"
- });
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON mms (thread_id);",
- "CREATE INDEX IF NOT EXISTS mms_read_index ON mms (read);",
- "CREATE INDEX IF NOT EXISTS mms_read_and_thread_id_index ON mms (read,thread_id);",
- "CREATE INDEX IF NOT EXISTS mms_message_box_index ON mms (msg_box);"
- });
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS part_mms_id_index ON part (mid);"
- });
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS thread_recipient_ids_index ON thread (recipient_ids);",
- });
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS mms_addresses_mms_id_index ON mms_addresses (mms_id);",
- });
- }
-
- if (oldVersion < INTRODUCED_DATE_SENT_VERSION) {
- db.execSQL("ALTER TABLE sms ADD COLUMN date_sent INTEGER;");
- db.execSQL("UPDATE sms SET date_sent = date;");
-
- db.execSQL("ALTER TABLE mms ADD COLUMN date_received INTEGER;");
- db.execSQL("UPDATE mms SET date_received = date;");
- }
-
- if (oldVersion < INTRODUCED_DRAFTS_VERSION) {
- db.execSQL("CREATE TABLE drafts (_id INTEGER PRIMARY KEY, thread_id INTEGER, type TEXT, value TEXT);");
- executeStatements(db, new String[] {
- "CREATE INDEX IF NOT EXISTS draft_thread_index ON drafts (thread_id);",
- });
- }
-
- if (oldVersion < INTRODUCED_NEW_TYPES_VERSION) {
- String KEY_EXCHANGE = "?TextSecureKeyExchange";
- String SYMMETRIC_ENCRYPT = "?TextSecureLocalEncrypt";
- String ASYMMETRIC_ENCRYPT = "?TextSecureAsymmetricEncrypt";
- String ASYMMETRIC_LOCAL_ENCRYPT = "?TextSecureAsymmetricLocalEncrypt";
- String PROCESSED_KEY_EXCHANGE = "?TextSecureKeyExchangd";
- String STALE_KEY_EXCHANGE = "?TextSecureKeyExchangs";
-
- // SMS Updates
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {20L+"", 1L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {21L+"", 43L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {22L+"", 4L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {23L+"", 2L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {24L+"", 5L+""});
-
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(21L | 0x800000L)+"", 42L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(23L | 0x800000L)+"", 44L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(20L | 0x800000L)+"", 45L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(20L | 0x800000L | 0x10000000L)+"", 46L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(20L)+"", 47L+""});
- db.execSQL("UPDATE sms SET type = ? WHERE type = ?", new String[] {(20L | 0x800000L | 0x08000000L)+"", 48L+""});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(SYMMETRIC_ENCRYPT.length()+1)+"",
- 0x80000000L+"",
- SYMMETRIC_ENCRYPT + "%"});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(ASYMMETRIC_LOCAL_ENCRYPT.length()+1)+"",
- 0x40000000L+"",
- ASYMMETRIC_LOCAL_ENCRYPT + "%"});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(ASYMMETRIC_ENCRYPT.length()+1)+"",
- (0x800000L | 0x20000000L)+"",
- ASYMMETRIC_ENCRYPT + "%"});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(KEY_EXCHANGE.length()+1)+"",
- 0x8000L+"",
- KEY_EXCHANGE + "%"});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(PROCESSED_KEY_EXCHANGE.length()+1)+"",
- (0x8000L | 0x2000L)+"",
- PROCESSED_KEY_EXCHANGE + "%"});
-
- db.execSQL("UPDATE sms SET body = substr(body, ?), type = type | ? WHERE body LIKE ?",
- new String[] {(STALE_KEY_EXCHANGE.length()+1)+"",
- (0x8000L | 0x4000L)+"",
- STALE_KEY_EXCHANGE + "%"});
-
- // MMS Updates
-
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(20L | 0x80000000L)+"", 1+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(23L | 0x80000000L)+"", 2+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(21L | 0x80000000L)+"", 4+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(24L | 0x80000000L)+"", 12+""});
-
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(21L | 0x80000000L | 0x800000L) +"", 5+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(23L | 0x80000000L | 0x800000L) +"", 6+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(20L | 0x20000000L | 0x800000L) +"", 7+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(20L | 0x80000000L | 0x800000L) +"", 8+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(20L | 0x08000000L | 0x800000L) +"", 9+""});
- db.execSQL("UPDATE mms SET msg_box = ? WHERE msg_box = ?", new String[] {(20L | 0x10000000L | 0x800000L) +"", 10+""});
-
- // Thread Updates
-
- db.execSQL("ALTER TABLE thread ADD COLUMN snippet_type INTEGER;");
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(SYMMETRIC_ENCRYPT.length()+1)+"",
- 0x80000000L+"",
- SYMMETRIC_ENCRYPT + "%"});
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(ASYMMETRIC_LOCAL_ENCRYPT.length()+1)+"",
- 0x40000000L+"",
- ASYMMETRIC_LOCAL_ENCRYPT + "%"});
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(ASYMMETRIC_ENCRYPT.length()+1)+"",
- (0x800000L | 0x20000000L)+"",
- ASYMMETRIC_ENCRYPT + "%"});
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(KEY_EXCHANGE.length()+1)+"",
- 0x8000L+"",
- KEY_EXCHANGE + "%"});
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(STALE_KEY_EXCHANGE.length()+1)+"",
- (0x8000L | 0x4000L)+"",
- STALE_KEY_EXCHANGE + "%"});
-
- db.execSQL("UPDATE thread SET snippet = substr(snippet, ?), " +
- "snippet_type = ? WHERE snippet LIKE ?",
- new String[] {(PROCESSED_KEY_EXCHANGE.length()+1)+"",
- (0x8000L | 0x2000L)+"",
- PROCESSED_KEY_EXCHANGE + "%"});
- }
-
- if (oldVersion < INTRODUCED_MMS_BODY_VERSION) {
- db.execSQL("ALTER TABLE mms ADD COLUMN body TEXT");
- db.execSQL("ALTER TABLE mms ADD COLUMN part_count INTEGER");
- }
-
- if (oldVersion < INTRODUCED_MMS_FROM_VERSION) {
- db.execSQL("ALTER TABLE mms ADD COLUMN address TEXT");
-
- Cursor cursor = db.query("mms_addresses", null, "type = ?", new String[] {0x89+""},
- null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long mmsId = cursor.getLong(cursor.getColumnIndexOrThrow("mms_id"));
- String address = cursor.getString(cursor.getColumnIndexOrThrow("address"));
-
- if (!TextUtils.isEmpty(address)) {
- db.execSQL("UPDATE mms SET address = ? WHERE _id = ?", new String[]{address, mmsId+""});
- }
- }
-
- if (cursor != null)
- cursor.close();
- }
-
- if (oldVersion < INTRODUCED_TOFU_IDENTITY_VERSION) {
- db.execSQL("DROP TABLE identities");
- db.execSQL("CREATE TABLE identities (_id INTEGER PRIMARY KEY, recipient INTEGER UNIQUE, key TEXT, mac TEXT);");
- }
-
- if (oldVersion < INTRODUCED_PUSH_DATABASE_VERSION) {
- db.execSQL("CREATE TABLE push (_id INTEGER PRIMARY KEY, type INTEGER, source TEXT, destinations TEXT, body TEXT, TIMESTAMP INTEGER);");
- db.execSQL("ALTER TABLE part ADD COLUMN pending_push INTEGER;");
- db.execSQL("CREATE INDEX IF NOT EXISTS pending_push_index ON part (pending_push);");
- }
-
- if (oldVersion < INTRODUCED_GROUP_DATABASE_VERSION) {
- db.execSQL("CREATE TABLE groups (_id INTEGER PRIMARY KEY, group_id TEXT, title TEXT, members TEXT, avatar BLOB, avatar_id INTEGER, avatar_key BLOB, avatar_content_type TEXT, avatar_relay TEXT, timestamp INTEGER, active INTEGER DEFAULT 1);");
- db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS group_id_index ON groups (GROUP_ID);");
- db.execSQL("ALTER TABLE push ADD COLUMN device_id INTEGER DEFAULT 1;");
- db.execSQL("ALTER TABLE sms ADD COLUMN address_device_id INTEGER DEFAULT 1;");
- db.execSQL("ALTER TABLE mms ADD COLUMN address_device_id INTEGER DEFAULT 1;");
- }
-
- if (oldVersion < INTRODUCED_PUSH_FIX_VERSION) {
- db.execSQL("CREATE TEMPORARY table push_backup (_id INTEGER PRIMARY KEY, type INTEGER, source, TEXT, destinations TEXT, body TEXT, timestamp INTEGER, device_id INTEGER DEFAULT 1);");
- db.execSQL("INSERT INTO push_backup(_id, type, source, body, timestamp, device_id) SELECT _id, type, source, body, timestamp, device_id FROM push;");
- db.execSQL("DROP TABLE push");
- db.execSQL("CREATE TABLE push (_id INTEGER PRIMARY KEY, type INTEGER, source TEXT, body TEXT, timestamp INTEGER, device_id INTEGER DEFAULT 1);");
- db.execSQL("INSERT INTO push (_id, type, source, body, timestamp, device_id) SELECT _id, type, source, body, timestamp, device_id FROM push_backup;");
- db.execSQL("DROP TABLE push_backup;");
- }
-
- if (oldVersion < INTRODUCED_DELIVERY_RECEIPTS) {
- db.execSQL("ALTER TABLE sms ADD COLUMN delivery_receipt_count INTEGER DEFAULT 0;");
- db.execSQL("ALTER TABLE mms ADD COLUMN delivery_receipt_count INTEGER DEFAULT 0;");
- db.execSQL("CREATE INDEX IF NOT EXISTS sms_date_sent_index ON sms (date_sent);");
- db.execSQL("CREATE INDEX IF NOT EXISTS mms_date_sent_index ON mms (date);");
- }
-
- if (oldVersion < INTRODUCED_PART_DATA_SIZE_VERSION) {
- db.execSQL("ALTER TABLE part ADD COLUMN data_size INTEGER DEFAULT 0;");
- }
-
- if (oldVersion < INTRODUCED_THUMBNAILS_VERSION) {
- db.execSQL("ALTER TABLE part ADD COLUMN thumbnail TEXT;");
- db.execSQL("ALTER TABLE part ADD COLUMN aspect_ratio REAL;");
- }
-
- if (oldVersion < INTRODUCED_IDENTITY_COLUMN_VERSION) {
- db.execSQL("ALTER TABLE sms ADD COLUMN mismatched_identities TEXT");
- db.execSQL("ALTER TABLE mms ADD COLUMN mismatched_identities TEXT");
- db.execSQL("ALTER TABLE mms ADD COLUMN network_failures TEXT");
- }
-
- if (oldVersion < INTRODUCED_UNIQUE_PART_IDS_VERSION) {
- db.execSQL("ALTER TABLE part ADD COLUMN unique_id INTEGER NOT NULL DEFAULT 0");
- }
-
- if (oldVersion < INTRODUCED_RECIPIENT_PREFS_DB) {
- db.execSQL("CREATE TABLE recipient_preferences " +
- "(_id INTEGER PRIMARY KEY, recipient_ids TEXT UNIQUE, block INTEGER DEFAULT 0, " +
- "notification TEXT DEFAULT NULL, vibrate INTEGER DEFAULT 0, mute_until INTEGER DEFAULT 0)");
- }
-
- if (oldVersion < INTRODUCED_ENVELOPE_CONTENT_VERSION) {
- db.execSQL("ALTER TABLE push ADD COLUMN content TEXT");
- }
-
- if (oldVersion < INTRODUCED_COLOR_PREFERENCE_VERSION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN color TEXT DEFAULT NULL");
- }
-
- if (oldVersion < INTRODUCED_DB_OPTIMIZATIONS_VERSION) {
- db.execSQL("UPDATE mms SET date_received = (date_received * 1000), date = (date * 1000);");
- db.execSQL("CREATE INDEX IF NOT EXISTS sms_thread_date_index ON sms (thread_id, date);");
- db.execSQL("CREATE INDEX IF NOT EXISTS mms_thread_date_index ON mms (thread_id, date_received);");
- }
-
- if (oldVersion < INTRODUCED_INVITE_REMINDERS_VERSION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN seen_invite_reminder INTEGER DEFAULT 0");
- }
-
- if (oldVersion < INTRODUCED_CONVERSATION_LIST_THUMBNAILS_VERSION) {
- db.execSQL("ALTER TABLE thread ADD COLUMN snippet_uri TEXT DEFAULT NULL");
- }
-
- if (oldVersion < INTRODUCED_ARCHIVE_VERSION) {
- db.execSQL("ALTER TABLE thread ADD COLUMN archived INTEGER DEFAULT 0");
- db.execSQL("CREATE INDEX IF NOT EXISTS archived_index ON thread (archived)");
- }
-
- if (oldVersion < INTRODUCED_CONVERSATION_LIST_STATUS_VERSION) {
- db.execSQL("ALTER TABLE thread ADD COLUMN status INTEGER DEFAULT -1");
- db.execSQL("ALTER TABLE thread ADD COLUMN delivery_receipt_count INTEGER DEFAULT 0");
- }
-
- if (oldVersion < MIGRATED_CONVERSATION_LIST_STATUS_VERSION) {
- Cursor threadCursor = db.query("thread", new String[] {"_id"}, null, null, null, null, null);
-
- while (threadCursor != null && threadCursor.moveToNext()) {
- long threadId = threadCursor.getLong(threadCursor.getColumnIndexOrThrow("_id"));
-
- Cursor cursor = db.rawQuery("SELECT DISTINCT date AS date_received, status, " +
- "delivery_receipt_count FROM sms WHERE (thread_id = ?1) " +
- "UNION ALL SELECT DISTINCT date_received, -1 AS status, " +
- "delivery_receipt_count FROM mms WHERE (thread_id = ?1) " +
- "ORDER BY date_received DESC LIMIT 1", new String[]{threadId + ""});
-
- if (cursor != null && cursor.moveToNext()) {
- int status = cursor.getInt(cursor.getColumnIndexOrThrow("status"));
- int receiptCount = cursor.getInt(cursor.getColumnIndexOrThrow("delivery_receipt_count"));
-
- db.execSQL("UPDATE thread SET status = ?, delivery_receipt_count = ? WHERE _id = ?",
- new String[]{status + "", receiptCount + "", threadId + ""});
- }
- }
- }
-
- if (oldVersion < INTRODUCED_SUBSCRIPTION_ID_VERSION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN default_subscription_id INTEGER DEFAULT -1");
- db.execSQL("ALTER TABLE sms ADD COLUMN subscription_id INTEGER DEFAULT -1");
- db.execSQL("ALTER TABLE mms ADD COLUMN subscription_id INTEGER DEFAULT -1");
- }
-
- if (oldVersion < INTRODUCED_EXPIRE_MESSAGES_VERSION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN expire_messages INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE sms ADD COLUMN expires_in INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN expires_in INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE sms ADD COLUMN expire_started INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN expire_started INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE thread ADD COLUMN expires_in INTEGER DEFAULT 0");
- }
-
- if (oldVersion < INTRODUCED_LAST_SEEN) {
- db.execSQL("ALTER TABLE thread ADD COLUMN last_seen INTEGER DEFAULT 0");
- }
-
- if (oldVersion < INTRODUCED_DIGEST) {
- db.execSQL("ALTER TABLE part ADD COLUMN digest BLOB");
- db.execSQL("ALTER TABLE groups ADD COLUMN avatar_digest BLOB");
- }
-
- if (oldVersion < INTRODUCED_NOTIFIED) {
- db.execSQL("ALTER TABLE sms ADD COLUMN notified INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN notified INTEGER DEFAULT 0");
-
- db.execSQL("DROP INDEX sms_read_and_thread_id_index");
- db.execSQL("CREATE INDEX IF NOT EXISTS sms_read_and_notified_and_thread_id_index ON sms(read,notified,thread_id)");
-
- db.execSQL("DROP INDEX mms_read_and_thread_id_index");
- db.execSQL("CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON mms(read,notified,thread_id)");
- }
-
- if (oldVersion < INTRODUCED_DOCUMENTS) {
- db.execSQL("ALTER TABLE part ADD COLUMN file_name TEXT");
- }
-
- if (oldVersion < INTRODUCED_FAST_PREFLIGHT) {
- db.execSQL("ALTER TABLE part ADD COLUMN fast_preflight_id TEXT");
- }
-
- if (oldVersion < INTRODUCED_VOICE_NOTES) {
- db.execSQL("ALTER TABLE part ADD COLUMN voice_note INTEGER DEFAULT 0");
- }
-
- if (oldVersion < INTRODUCED_IDENTITY_TIMESTAMP) {
- db.execSQL("ALTER TABLE identities ADD COLUMN timestamp INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE identities ADD COLUMN first_use INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE identities ADD COLUMN nonblocking_approval INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE identities ADD COLUMN verified INTEGER DEFAULT 0");
-
- db.execSQL("DROP INDEX archived_index");
- db.execSQL("CREATE INDEX IF NOT EXISTS archived_count_index ON thread (archived, message_count)");
- }
-
- if (oldVersion < SANIFY_ATTACHMENT_DOWNLOAD) {
- db.execSQL("UPDATE part SET pending_push = '2' WHERE pending_push = '1'");
- }
-
- if (oldVersion < NO_MORE_CANONICAL_ADDRESS_DATABASE) {
- SQLiteOpenHelper canonicalAddressDatabaseHelper = new SQLiteOpenHelper(context, "canonical_address.db", null, 1) {
- @Override
- public void onCreate(SQLiteDatabase db) {
- throw new AssertionError("No canonical address DB?");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
- };
-
- SQLiteDatabase canonicalAddressDatabase = canonicalAddressDatabaseHelper.getReadableDatabase();
- NumberMigrator numberMigrator = new NumberMigrator(TextSecurePreferences.getLocalNumber(context));
-
- // Migrate Thread Database
- Cursor cursor = db.query("thread", new String[] {"_id", "recipient_ids"}, null, null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long threadId = cursor.getLong(0);
- String recipientIdsList = cursor.getString(1);
- String[] recipientIds = recipientIdsList.split(" ");
- String[] addresses = new String[recipientIds.length];
-
- for (int i=0;i newDocumentList = new LinkedList<>();
-
- for (PreCanonicalAddressIdentityMismatchDocument oldDocument : oldDocumentList.list) {
- Cursor resolved = canonicalAddressDatabase.query("canonical_addresses", new String[] {"address"}, "_id = ?", new String[] {String.valueOf(oldDocument.recipientId)}, null, null, null);
-
- if (resolved != null && resolved.moveToFirst()) {
- String address = resolved.getString(0);
- newDocumentList.add(new PostCanonicalAddressIdentityMismatchDocument(numberMigrator.migrate(address), oldDocument.identityKey));
- } else {
- throw new AssertionError("Unable to resolve: " + oldDocument.recipientId);
- }
-
- if (resolved != null) resolved.close();
- }
-
- ContentValues values = new ContentValues(1);
- values.put("mismatched_identities", JsonUtils.toJson(new PostCanonicalAddressIdentityMismatchList(newDocumentList)));
- db.update("sms", values, "_id = ?", new String[] {String.valueOf(id)});
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
- }
-
- if (cursor != null) cursor.close();
-
- // Migrate MMS mismatched identities
- cursor = db.query("mms", new String[] {"_id", "mismatched_identities"}, "mismatched_identities IS NOT NULL", null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String document = cursor.getString(1);
-
- if (!TextUtils.isEmpty(document)) {
- try {
- PreCanonicalAddressIdentityMismatchList oldDocumentList = JsonUtils.fromJson(document, PreCanonicalAddressIdentityMismatchList.class);
- List newDocumentList = new LinkedList<>();
-
- for (PreCanonicalAddressIdentityMismatchDocument oldDocument : oldDocumentList.list) {
- Cursor resolved = canonicalAddressDatabase.query("canonical_addresses", new String[] {"address"}, "_id = ?", new String[] {String.valueOf(oldDocument.recipientId)}, null, null, null);
-
- if (resolved != null && resolved.moveToFirst()) {
- String address = resolved.getString(0);
- newDocumentList.add(new PostCanonicalAddressIdentityMismatchDocument(numberMigrator.migrate(address), oldDocument.identityKey));
- } else {
- throw new AssertionError("Unable to resolve: " + oldDocument.recipientId);
- }
-
- if (resolved != null) resolved.close();
- }
-
- ContentValues values = new ContentValues(1);
- values.put("mismatched_identities", JsonUtils.toJson(new PostCanonicalAddressIdentityMismatchList(newDocumentList)));
- db.update("mms", values, "_id = ?", new String[] {String.valueOf(id)});
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
- }
-
- if (cursor != null) cursor.close();
-
- // Migrate MMS network failures
- cursor = db.query("mms", new String[] {"_id", "network_failures"}, "network_failures IS NOT NULL", null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String document = cursor.getString(1);
-
- if (!TextUtils.isEmpty(document)) {
- try {
- PreCanonicalAddressNetworkFailureList oldDocumentList = JsonUtils.fromJson(document, PreCanonicalAddressNetworkFailureList.class);
- List newDocumentList = new LinkedList<>();
-
- for (PreCanonicalAddressNetworkFailureDocument oldDocument : oldDocumentList.list) {
- Cursor resolved = canonicalAddressDatabase.query("canonical_addresses", new String[] {"address"}, "_id = ?", new String[] {String.valueOf(oldDocument.recipientId)}, null, null, null);
-
- if (resolved != null && resolved.moveToFirst()) {
- String address = resolved.getString(0);
- newDocumentList.add(new PostCanonicalAddressNetworkFailureDocument(numberMigrator.migrate(address)));
- } else {
- throw new AssertionError("Unable to resolve: " + oldDocument.recipientId);
- }
-
- if (resolved != null) resolved.close();
- }
-
- ContentValues values = new ContentValues(1);
- values.put("network_failures", JsonUtils.toJson(new PostCanonicalAddressNetworkFailureList(newDocumentList)));
- db.update("mms", values, "_id = ?", new String[] {String.valueOf(id)});
- } catch (IOException e) {
- Log.w(TAG, e);
- }
- }
- }
-
- // Migrate sessions
- File sessionsDirectory = new File(context.getFilesDir(), "sessions-v2");
-
- if (sessionsDirectory.exists() && sessionsDirectory.isDirectory()) {
- File[] sessions = sessionsDirectory.listFiles();
-
- for (File session : sessions) {
- try {
- String[] sessionParts = session.getName().split("[.]");
- long recipientId = Long.parseLong(sessionParts[0]);
-
- int deviceId;
-
- if (sessionParts.length > 1) deviceId = Integer.parseInt(sessionParts[1]);
- else deviceId = 1;
-
- Cursor resolved = canonicalAddressDatabase.query("canonical_addresses", new String[] {"address"}, "_id = ?", new String[] {String.valueOf(recipientId)}, null, null, null);
-
- if (resolved != null && resolved.moveToNext()) {
- String address = resolved.getString(0);
- File destination = new File(session.getParentFile(), address + (deviceId != 1 ? "." + deviceId : ""));
-
- if (!session.renameTo(destination)) {
- Log.w(TAG, "Session rename failed: " + destination);
- }
- }
-
- if (resolved != null) resolved.close();
- } catch (NumberFormatException e) {
- Log.w(TAG, e);
- }
- }
- }
-
- }
-
- if (oldVersion < NO_MORE_RECIPIENTS_PLURAL) {
- db.execSQL("ALTER TABLE groups ADD COLUMN mms INTEGER DEFAULT 0");
-
- Cursor cursor = db.query("thread", new String[] {"_id", "recipient_ids"}, null, null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long threadId = cursor.getLong(0);
- String addressListString = cursor.getString(1);
- String[] addressList = DelimiterUtil.split(addressListString, ' ');
-
- if (addressList.length == 1) {
- ContentValues contentValues = new ContentValues();
- contentValues.put("recipient_ids", DelimiterUtil.unescape(addressListString, ' '));
- db.update("thread", contentValues, "_id = ?", new String[] {String.valueOf(threadId)});
- } else {
- byte[] groupId = new byte[16];
- List members = new LinkedList<>();
-
- new SecureRandom().nextBytes(groupId);
-
- for (String address : addressList) {
- members.add(DelimiterUtil.escape(DelimiterUtil.unescape(address, ' '), ','));
- }
-
- members.add(DelimiterUtil.escape(TextSecurePreferences.getLocalNumber(context), ','));
-
- Collections.sort(members);
-
- String encodedGroupId = "__signal_mms_group__!" + Hex.toStringCondensed(groupId);
- ContentValues groupValues = new ContentValues();
- ContentValues threadValues = new ContentValues();
-
- groupValues.put("group_id", encodedGroupId);
- groupValues.put("members", Util.join(members, ","));
- groupValues.put("mms", 1);
-
- threadValues.put("recipient_ids", encodedGroupId);
-
- db.insert("groups", null, groupValues);
- db.update("thread", threadValues, "_id = ?", new String[] {String.valueOf(threadId)});
- db.update("recipient_preferences", threadValues, "recipient_ids = ?", new String[] {addressListString});
- }
- }
-
- if (cursor != null) cursor.close();
-
- cursor = db.query("recipient_preferences", new String[] {"_id", "recipient_ids"}, null, null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String addressListString = cursor.getString(1);
- String[] addressList = DelimiterUtil.split(addressListString, ' ');
-
- if (addressList.length == 1) {
- ContentValues contentValues = new ContentValues();
- contentValues.put("recipient_ids", DelimiterUtil.unescape(addressListString, ' '));
- db.update("recipient_preferences", contentValues, "_id = ?", new String[] {String.valueOf(id)});
- } else {
- Log.w(TAG, "Found preferences for MMS thread that appears to be gone: " + addressListString);
- db.delete("recipient_preferences", "_id = ?", new String[] {String.valueOf(id)});
- }
- }
-
- if (cursor != null) cursor.close();
-
- cursor = db.rawQuery("SELECT mms._id, thread.recipient_ids FROM mms, thread WHERE mms.address IS NULL AND mms.thread_id = thread._id", null);
-
- while (cursor != null && cursor.moveToNext()) {
- long id = cursor.getLong(0);
- ContentValues contentValues = new ContentValues(1);
-
- contentValues.put("address", cursor.getString(1));
- db.update("mms", contentValues, "_id = ?", new String[] {String.valueOf(id)});
- }
-
- if (cursor != null) cursor.close();
- }
-
- if (oldVersion < INTERNAL_DIRECTORY) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN registered INTEGER DEFAULT 0");
-
- OldDirectoryDatabaseHelper directoryDatabaseHelper = new OldDirectoryDatabaseHelper(context);
- SQLiteDatabase directoryDatabase = directoryDatabaseHelper.getWritableDatabase();
-
- Cursor cursor = directoryDatabase.query("directory", new String[] {"number", "registered"}, null, null, null, null, null);
-
- while (cursor != null && cursor.moveToNext()) {
- String address = new NumberMigrator(TextSecurePreferences.getLocalNumber(context)).migrate(cursor.getString(0));
- ContentValues contentValues = new ContentValues(1);
-
- contentValues.put("registered", cursor.getInt(1) == 1 ? 1 : 2);
-
- if (db.update("recipient_preferences", contentValues, "recipient_ids = ?", new String[] {address}) < 1) {
- contentValues.put("recipient_ids", address);
- db.insert("recipient_preferences", null, contentValues);
- }
- }
-
- if (cursor != null) cursor.close();
- }
-
- if (oldVersion < INTERNAL_SYSTEM_DISPLAY_NAME) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN system_display_name TEXT DEFAULT NULL");
- }
-
- if (oldVersion < PROFILES) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN profile_key TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN signal_profile_name TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN signal_profile_avatar TEXT DEFAULT NULL");
- }
-
- if (oldVersion < PROFILE_SHARING_APPROVAL) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN profile_sharing_approval INTEGER DEFAULT 0");
- }
-
- if (oldVersion < UNSEEN_NUMBER_OFFER) {
- db.execSQL("ALTER TABLE thread ADD COLUMN has_sent INTEGER DEFAULT 0");
- }
-
- if (oldVersion < READ_RECEIPTS) {
- db.execSQL("ALTER TABLE sms ADD COLUMN read_receipt_count INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN read_receipt_count INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE thread ADD COLUMN read_receipt_count INTEGER DEFAULT 0");
- }
-
- if (oldVersion < GROUP_RECEIPT_TRACKING) {
- db.execSQL("CREATE TABLE group_receipts (_id INTEGER PRIMARY KEY, mms_id INTEGER, address TEXT, status INTEGER, timestamp INTEGER)");
- db.execSQL("CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON group_receipts (mms_id)");
- }
-
- if (oldVersion < UNREAD_COUNT_VERSION) {
- db.execSQL("ALTER TABLE thread ADD COLUMN unread_count INTEGER DEFAULT 0");
-
- try (Cursor cursor = db.query("thread", new String[] {"_id"}, "read = 0", null, null, null, null)) {
- while (cursor != null && cursor.moveToNext()) {
- long threadId = cursor.getLong(0);
- int unreadCount = 0;
-
- try (Cursor smsCursor = db.rawQuery("SELECT COUNT(*) FROM sms WHERE thread_id = ? AND read = '0'", new String[] {String.valueOf(threadId)})) {
- if (smsCursor != null && smsCursor.moveToFirst()) {
- unreadCount += smsCursor.getInt(0);
- }
- }
-
- try (Cursor mmsCursor = db.rawQuery("SELECT COUNT(*) FROM mms WHERE thread_id = ? AND read = '0'", new String[] {String.valueOf(threadId)})) {
- if (mmsCursor != null && mmsCursor.moveToFirst()) {
- unreadCount += mmsCursor.getInt(0);
- }
- }
-
- db.execSQL("UPDATE thread SET unread_count = ? WHERE _id = ?",
- new String[] {String.valueOf(unreadCount),
- String.valueOf(threadId)});
- }
- }
- }
-
- if (oldVersion < MORE_RECIPIENT_FIELDS) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN system_contact_photo TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN system_phone_label TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN system_contact_uri TEXT DEFAULT NULL");
- /*
- if (Permissions.hasAny(context, Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS)) {
- try (Cursor cursor = db.query("recipient_preferences", null, null, null, null, null, null)) {
- while (cursor != null && cursor.moveToNext()) {
- Address address = Address.fromSerialized(cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids")));
-
- if (address.isPhone() && !TextUtils.isEmpty(address.toPhoneString())) {
- Uri lookup = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address.toPhoneString()));
-
- try (Cursor contactCursor = context.getContentResolver().query(lookup, new String[] {ContactsContract.PhoneLookup.DISPLAY_NAME,
- ContactsContract.PhoneLookup.LOOKUP_KEY,
- ContactsContract.PhoneLookup._ID,
- ContactsContract.PhoneLookup.NUMBER,
- ContactsContract.PhoneLookup.LABEL,
- ContactsContract.PhoneLookup.PHOTO_URI},
- null, null, null))
- {
- if (contactCursor != null && contactCursor.moveToFirst()) {
- ContentValues contentValues = new ContentValues(3);
- contentValues.put("system_contact_photo", contactCursor.getString(5));
- contentValues.put("system_phone_label", contactCursor.getString(4));
- contentValues.put("system_contact_uri", ContactsContract.Contacts.getLookupUri(contactCursor.getLong(2), contactCursor.getString(1)).toString());
-
- db.update("recipient_preferences", contentValues, "recipient_ids = ?", new String[] {address.toPhoneString()});
- }
- }
- }
- }
- }
- }
- */
- }
-
- db.setTransactionSuccessful();
- db.endTransaction();
- }
-
- private void executeStatements(SQLiteDatabase db, String[] statements) {
- for (String statement : statements)
- db.execSQL(statement);
- }
-
- private static class PreCanonicalAddressIdentityMismatchList {
- @JsonProperty(value = "m")
- private List list;
- }
-
- private static class PostCanonicalAddressIdentityMismatchList {
- @JsonProperty(value = "m")
- private List list;
-
- public PostCanonicalAddressIdentityMismatchList(List list) {
- this.list = list;
- }
- }
-
- private static class PreCanonicalAddressIdentityMismatchDocument {
- @JsonProperty(value = "r")
- private long recipientId;
-
- @JsonProperty(value = "k")
- private String identityKey;
- }
-
- private static class PostCanonicalAddressIdentityMismatchDocument {
- @JsonProperty(value = "a")
- private String address;
-
- @JsonProperty(value = "k")
- private String identityKey;
-
- public PostCanonicalAddressIdentityMismatchDocument() {}
-
- public PostCanonicalAddressIdentityMismatchDocument(String address, String identityKey) {
- this.address = address;
- this.identityKey = identityKey;
- }
- }
-
- private static class PreCanonicalAddressNetworkFailureList {
- @JsonProperty(value = "l")
- private List list;
- }
-
- private static class PostCanonicalAddressNetworkFailureList {
- @JsonProperty(value = "l")
- private List list;
-
- public PostCanonicalAddressNetworkFailureList(List list) {
- this.list = list;
- }
- }
-
- private static class PreCanonicalAddressNetworkFailureDocument {
- @JsonProperty(value = "r")
- private long recipientId;
- }
-
- private static class PostCanonicalAddressNetworkFailureDocument {
- @JsonProperty(value = "a")
- private String address;
-
- public PostCanonicalAddressNetworkFailureDocument() {}
-
- public PostCanonicalAddressNetworkFailureDocument(String address) {
- this.address = address;
- }
- }
-
- private static class NumberMigrator {
-
- private static final String TAG = NumberMigrator.class.getSimpleName();
-
- private static final Set SHORT_COUNTRIES = new HashSet() {{
- add("NU");
- add("TK");
- add("NC");
- add("AC");
- }};
-
- private final String localNumberString;
-
- private final Pattern ALPHA_PATTERN = Pattern.compile("[a-zA-Z]");
-
-
- public NumberMigrator(String localNumber) {
- this.localNumberString = localNumber;
- }
-
- public String migrate(@Nullable String number) {
- if (number == null) return "Unknown";
- return number;
- }
- }
-
- private static class OldDirectoryDatabaseHelper extends SQLiteOpenHelper {
-
- private static final int INTRODUCED_CHANGE_FROM_TOKEN_TO_E164_NUMBER = 2;
- private static final int INTRODUCED_VOICE_COLUMN = 4;
- private static final int INTRODUCED_VIDEO_COLUMN = 5;
-
- private static final String DATABASE_NAME = "whisper_directory.db";
- private static final int DATABASE_VERSION = 5;
-
- private static final String TABLE_NAME = "directory";
- private static final String ID = "_id";
- private static final String NUMBER = "number";
- private static final String REGISTERED = "registered";
- private static final String RELAY = "relay";
- private static final String TIMESTAMP = "timestamp";
- private static final String VOICE = "voice";
- private static final String VIDEO = "video";
-
- private static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + ID + " INTEGER PRIMARY KEY, " +
- NUMBER + " TEXT UNIQUE, " +
- REGISTERED + " INTEGER, " +
- RELAY + " TEXT, " +
- TIMESTAMP + " INTEGER, " +
- VOICE + " INTEGER, " +
- VIDEO + " INTEGER);";
-
- public OldDirectoryDatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL(CREATE_TABLE);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion < INTRODUCED_CHANGE_FROM_TOKEN_TO_E164_NUMBER) {
- db.execSQL("DROP TABLE directory;");
- db.execSQL("CREATE TABLE directory ( _id INTEGER PRIMARY KEY, " +
- "number TEXT UNIQUE, " +
- "registered INTEGER, " +
- "relay TEXT, " +
- "supports_sms INTEGER, " +
- "timestamp INTEGER);");
- }
-
- if (oldVersion < INTRODUCED_VOICE_COLUMN) {
- db.execSQL("ALTER TABLE directory ADD COLUMN voice INTEGER;");
- }
-
- if (oldVersion < INTRODUCED_VIDEO_COLUMN) {
- db.execSQL("ALTER TABLE directory ADD COLUMN video INTEGER;");
- }
- }
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java
deleted file mode 100644
index dde6634801..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherMigrationHelper.java
+++ /dev/null
@@ -1,254 +0,0 @@
-package org.thoughtcrime.securesms.database.helpers;
-
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import android.text.TextUtils;
-import org.thoughtcrime.securesms.logging.Log;
-import android.util.Pair;
-
-import com.annimon.stream.function.BiFunction;
-
-import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
-import network.loki.messenger.R;
-import org.thoughtcrime.securesms.crypto.AsymmetricMasterCipher;
-import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider;
-import org.thoughtcrime.securesms.crypto.MasterCipher;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
-import org.thoughtcrime.securesms.service.GenericForegroundService;
-import org.thoughtcrime.securesms.util.Base64;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-import org.session.libsignal.libsignal.InvalidMessageException;
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-public class SQLCipherMigrationHelper {
-
- private static final String TAG = SQLCipherMigrationHelper.class.getSimpleName();
-
- private static final long ENCRYPTION_SYMMETRIC_BIT = 0x80000000;
- private static final long ENCRYPTION_ASYMMETRIC_BIT = 0x40000000;
-
- static void migratePlaintext(@NonNull Context context,
- @NonNull android.database.sqlite.SQLiteDatabase legacyDb,
- @NonNull net.sqlcipher.database.SQLiteDatabase modernDb)
- {
- modernDb.beginTransaction();
- try {
- GenericForegroundService.startForegroundTask(context, context.getString(R.string.SQLCipherMigrationHelper_migrating_signal_database));
- copyTable("identities", legacyDb, modernDb, null);
- copyTable("push", legacyDb, modernDb, null);
- copyTable("groups", legacyDb, modernDb, null);
- copyTable("recipient_preferences", legacyDb, modernDb, null);
- copyTable("group_receipts", legacyDb, modernDb, null);
- modernDb.setTransactionSuccessful();
- } finally {
- modernDb.endTransaction();
- GenericForegroundService.stopForegroundTask(context);
- }
- }
-
- public static void migrateCiphertext(@NonNull Context context,
- @NonNull MasterSecret masterSecret,
- @NonNull android.database.sqlite.SQLiteDatabase legacyDb,
- @NonNull net.sqlcipher.database.SQLiteDatabase modernDb,
- @Nullable DatabaseUpgradeActivity.DatabaseUpgradeListener listener)
- {
- MasterCipher legacyCipher = new MasterCipher(masterSecret);
- AsymmetricMasterCipher legacyAsymmetricCipher = new AsymmetricMasterCipher(MasterSecretUtil.getAsymmetricMasterSecret(context, masterSecret));
-
- modernDb.beginTransaction();
-
- try {
- GenericForegroundService.startForegroundTask(context, context.getString(R.string.SQLCipherMigrationHelper_migrating_signal_database));
- int total = 5000;
-
- copyTable("sms", legacyDb, modernDb, (row, progress) -> {
- Pair plaintext = getPlaintextBody(legacyCipher, legacyAsymmetricCipher,
- row.getAsLong("type"),
- row.getAsString("body"));
-
- row.put("body", plaintext.second);
- row.put("type", plaintext.first);
-
- if (listener != null && (progress.first % 1000 == 0)) {
- listener.setProgress(getTotalProgress(0, progress.first, progress.second), total);
- }
-
- return row;
- });
-
- copyTable("mms", legacyDb, modernDb, (row, progress) -> {
- Pair plaintext = getPlaintextBody(legacyCipher, legacyAsymmetricCipher,
- row.getAsLong("msg_box"),
- row.getAsString("body"));
-
- row.put("body", plaintext.second);
- row.put("msg_box", plaintext.first);
-
- if (listener != null && (progress.first % 1000 == 0)) {
- listener.setProgress(getTotalProgress(1000, progress.first, progress.second), total);
- }
-
- return row;
- });
-
- copyTable("part", legacyDb, modernDb, (row, progress) -> {
- String fileName = row.getAsString("file_name");
- String mediaKey = row.getAsString("cd");
-
- try {
- if (!TextUtils.isEmpty(fileName)) {
- row.put("file_name", legacyCipher.decryptBody(fileName));
- }
- } catch (InvalidMessageException e) {
- Log.w(TAG, e);
- }
-
- try {
- if (!TextUtils.isEmpty(mediaKey)) {
- byte[] plaintext;
-
- if (mediaKey.startsWith("?ASYNC-")) {
- plaintext = legacyAsymmetricCipher.decryptBytes(Base64.decode(mediaKey.substring("?ASYNC-".length())));
- } else {
- plaintext = legacyCipher.decryptBytes(Base64.decode(mediaKey));
- }
-
- row.put("cd", Base64.encodeBytes(plaintext));
- }
- } catch (IOException | InvalidMessageException e) {
- Log.w(TAG, e);
- }
-
- if (listener != null && (progress.first % 1000 == 0)) {
- listener.setProgress(getTotalProgress(2000, progress.first, progress.second), total);
- }
-
- return row;
- });
-
- copyTable("thread", legacyDb, modernDb, (row, progress) -> {
- Long snippetType = row.getAsLong("snippet_type");
- if (snippetType == null) snippetType = 0L;
-
- Pair plaintext = getPlaintextBody(legacyCipher, legacyAsymmetricCipher,
- snippetType, row.getAsString("snippet"));
-
- row.put("snippet", plaintext.second);
- row.put("snippet_type", plaintext.first);
-
- if (listener != null && (progress.first % 1000 == 0)) {
- listener.setProgress(getTotalProgress(3000, progress.first, progress.second), total);
- }
-
- return row;
- });
-
-
- copyTable("drafts", legacyDb, modernDb, (row, progress) -> {
- String draftType = row.getAsString("type");
- String draft = row.getAsString("value");
-
- try {
- if (!TextUtils.isEmpty(draftType)) row.put("type", legacyCipher.decryptBody(draftType));
- if (!TextUtils.isEmpty(draft)) row.put("value", legacyCipher.decryptBody(draft));
- } catch (InvalidMessageException e) {
- Log.w(TAG, e);
- }
-
- if (listener != null && (progress.first % 1000 == 0)) {
- listener.setProgress(getTotalProgress(4000, progress.first, progress.second), total);
- }
-
- return row;
- });
-
- AttachmentSecretProvider.getInstance(context).setClassicKey(context, masterSecret.getEncryptionKey().getEncoded(), masterSecret.getMacKey().getEncoded());
- TextSecurePreferences.setNeedsSqlCipherMigration(context, false);
- modernDb.setTransactionSuccessful();
- } finally {
- modernDb.endTransaction();
- GenericForegroundService.stopForegroundTask(context);
- }
- }
-
- private static void copyTable(@NonNull String tableName,
- @NonNull android.database.sqlite.SQLiteDatabase legacyDb,
- @NonNull net.sqlcipher.database.SQLiteDatabase modernDb,
- @Nullable BiFunction, ContentValues> transformer)
- {
- Set destinationColumns = getTableColumns(tableName, modernDb);
-
- try (Cursor cursor = legacyDb.query(tableName, null, null, null, null, null, null)) {
- int count = (cursor != null) ? cursor.getCount() : 0;
- int progress = 1;
-
- while (cursor != null && cursor.moveToNext()) {
- ContentValues row = new ContentValues();
-
- for (int i=0;i(progress++, count));
- }
-
- modernDb.insert(tableName, null, row);
- }
- }
- }
-
- private static Pair getPlaintextBody(@NonNull MasterCipher legacyCipher,
- @NonNull AsymmetricMasterCipher legacyAsymmetricCipher,
- long type,
- @Nullable String body)
- {
- try {
- if (!TextUtils.isEmpty(body)) {
- if ((type & ENCRYPTION_SYMMETRIC_BIT) != 0) body = legacyCipher.decryptBody(body);
- else if ((type & ENCRYPTION_ASYMMETRIC_BIT) != 0) body = legacyAsymmetricCipher.decryptBody(body);
- }
- } catch (InvalidMessageException | IOException e) {
- Log.w(TAG, e);
- }
-
- type &= ~(ENCRYPTION_SYMMETRIC_BIT);
- type &= ~(ENCRYPTION_ASYMMETRIC_BIT);
-
- return new Pair<>(type, body);
- }
-
- private static Set getTableColumns(String tableName, net.sqlcipher.database.SQLiteDatabase database) {
- Set results = new HashSet<>();
-
- try (Cursor cursor = database.rawQuery("PRAGMA table_info(" + tableName + ")", null)) {
- while (cursor != null && cursor.moveToNext()) {
- results.add(cursor.getString(1));
- }
- }
-
- return results;
- }
-
- private static int getTotalProgress(int sectionOffset, int sectionProgress, int sectionTotal) {
- double percentOfSectionComplete = ((double)sectionProgress) / ((double)sectionTotal);
- return sectionOffset + (int)(((double)1000) * percentOfSectionComplete);
- }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
index 19facfe0e5..1fa0ccedd2 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java
@@ -1,12 +1,8 @@
package org.thoughtcrime.securesms.database.helpers;
-import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
-import android.net.Uri;
-import android.os.SystemClock;
-import android.text.TextUtils;
import androidx.annotation.NonNull;
@@ -14,10 +10,7 @@ import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteDatabaseHook;
import net.sqlcipher.database.SQLiteOpenHelper;
-import org.session.libsignal.service.loki.api.opengroups.PublicChat;
import org.thoughtcrime.securesms.crypto.DatabaseSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.database.AttachmentDatabase;
import org.thoughtcrime.securesms.database.DraftDatabase;
import org.thoughtcrime.securesms.database.GroupDatabase;
@@ -40,44 +33,14 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.database.LokiUserDatabase;
import org.thoughtcrime.securesms.loki.database.SharedSenderKeysDatabase;
-import org.thoughtcrime.securesms.notifications.NotificationChannels;
-import org.thoughtcrime.securesms.service.KeyCachingService;
-import org.thoughtcrime.securesms.util.GroupUtil;
-import org.thoughtcrime.securesms.util.TextSecurePreferences;
-
-import java.io.File;
public class SQLCipherOpenHelper extends SQLiteOpenHelper {
@SuppressWarnings("unused")
private static final String TAG = SQLCipherOpenHelper.class.getSimpleName();
- private static final int RECIPIENT_CALL_RINGTONE_VERSION = 2;
- private static final int MIGRATE_PREKEYS_VERSION = 3;
- private static final int MIGRATE_SESSIONS_VERSION = 4;
- private static final int NO_MORE_IMAGE_THUMBNAILS_VERSION = 5;
- private static final int ATTACHMENT_DIMENSIONS = 6;
- private static final int QUOTED_REPLIES = 7;
- private static final int SHARED_CONTACTS = 8;
- private static final int FULL_TEXT_SEARCH = 9;
- private static final int BAD_IMPORT_CLEANUP = 10;
- private static final int QUOTE_MISSING = 11;
- private static final int NOTIFICATION_CHANNELS = 12;
- private static final int SECRET_SENDER = 13;
- private static final int ATTACHMENT_CAPTIONS = 14;
- private static final int ATTACHMENT_CAPTIONS_FIX = 15;
- private static final int PREVIEWS = 16;
- private static final int CONVERSATION_SEARCH = 17;
- private static final int SELF_ATTACHMENT_CLEANUP = 18;
- private static final int RECIPIENT_FORCE_SMS_SELECTION = 19;
- private static final int JOBMANAGER_STRIKES_BACK = 20;
- private static final int STICKERS = 21;
- private static final int lokiV1 = 22;
- private static final int lokiV2 = 23;
- private static final int lokiV3 = 24;
- private static final int lokiV4 = 25;
- private static final int lokiV5 = 26;
- private static final int lokiV6 = 27;
+ // First public release (1.0.0) DB version was 27.
+ // So we have to keep the migrations onwards.
private static final int lokiV7 = 28;
private static final int lokiV8 = 29;
private static final int lokiV9 = 30;
@@ -177,20 +140,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
executeStatements(db, GroupDatabase.CREATE_INDEXS);
executeStatements(db, GroupReceiptDatabase.CREATE_INDEXES);
executeStatements(db, StickerDatabase.CREATE_INDEXES);
-
- if (context.getDatabasePath(ClassicOpenHelper.NAME).exists()) {
- ClassicOpenHelper legacyHelper = new ClassicOpenHelper(context);
- android.database.sqlite.SQLiteDatabase legacyDb = legacyHelper.getWritableDatabase();
-
- SQLCipherMigrationHelper.migratePlaintext(context, legacyDb, db);
-
- MasterSecret masterSecret = KeyCachingService.getMasterSecret(context);
-
- if (masterSecret != null) SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, legacyDb, db, null);
- else TextSecurePreferences.setNeedsSqlCipherMigration(context, true);
-
- SessionStoreMigrationHelper.migrateSessions(context, db);
- }
}
@Override
@@ -210,379 +159,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
try {
- if (oldVersion < RECIPIENT_CALL_RINGTONE_VERSION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_ringtone TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN call_vibrate INTEGER DEFAULT " + RecipientDatabase.VibrateState.DEFAULT.getId());
- }
-
- if (oldVersion < MIGRATE_PREKEYS_VERSION) {
- db.execSQL("CREATE TABLE signed_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL, signature TEXT NOT NULL, timestamp INTEGER DEFAULT 0)");
- db.execSQL("CREATE TABLE one_time_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL)");
- }
-
- if (oldVersion < MIGRATE_SESSIONS_VERSION) {
- db.execSQL("CREATE TABLE sessions (_id INTEGER PRIMARY KEY, address TEXT NOT NULL, device INTEGER NOT NULL, record BLOB NOT NULL, UNIQUE(address, device) ON CONFLICT REPLACE)");
- SessionStoreMigrationHelper.migrateSessions(context, db);
- }
-
- if (oldVersion < NO_MORE_IMAGE_THUMBNAILS_VERSION) {
- ContentValues update = new ContentValues();
- update.put("thumbnail", (String)null);
- update.put("aspect_ratio", (String)null);
- update.put("thumbnail_random", (String)null);
-
- try (Cursor cursor = db.query("part", new String[] {"_id", "ct", "thumbnail"}, "thumbnail IS NOT NULL", null, null, null, null)) {
- while (cursor != null && cursor.moveToNext()) {
- long id = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
- String contentType = cursor.getString(cursor.getColumnIndexOrThrow("ct"));
-
- if (contentType != null && !contentType.startsWith("video")) {
- String thumbnailPath = cursor.getString(cursor.getColumnIndexOrThrow("thumbnail"));
- File thumbnailFile = new File(thumbnailPath);
- thumbnailFile.delete();
-
- db.update("part", update, "_id = ?", new String[] {String.valueOf(id)});
- }
- }
- }
- }
-
- if (oldVersion < ATTACHMENT_DIMENSIONS) {
- db.execSQL("ALTER TABLE part ADD COLUMN width INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE part ADD COLUMN height INTEGER DEFAULT 0");
- }
-
- if (oldVersion < QUOTED_REPLIES) {
- db.execSQL("ALTER TABLE mms ADD COLUMN quote_id INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN quote_author TEXT");
- db.execSQL("ALTER TABLE mms ADD COLUMN quote_body TEXT");
- db.execSQL("ALTER TABLE mms ADD COLUMN quote_attachment INTEGER DEFAULT -1");
-
- db.execSQL("ALTER TABLE part ADD COLUMN quote INTEGER DEFAULT 0");
- }
-
- if (oldVersion < SHARED_CONTACTS) {
- db.execSQL("ALTER TABLE mms ADD COLUMN shared_contacts TEXT");
- }
-
- if (oldVersion < FULL_TEXT_SEARCH) {
- db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, content=sms, content_rowid=_id)");
- db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN\n" +
- " INSERT INTO sms_fts(rowid, body) VALUES (new._id, new.body);\n" +
- "END;");
- db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN\n" +
- " INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" +
- "END;\n");
- db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN\n" +
- " INSERT INTO sms_fts(sms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" +
- " INSERT INTO sms_fts(rowid, body) VALUES(new._id, new.body);\n" +
- "END;");
-
- db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, content=mms, content_rowid=_id)");
- db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN\n" +
- " INSERT INTO mms_fts(rowid, body) VALUES (new._id, new.body);\n" +
- "END;");
- db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN\n" +
- " INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" +
- "END;\n");
- db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN\n" +
- " INSERT INTO mms_fts(mms_fts, rowid, body) VALUES('delete', old._id, old.body);\n" +
- " INSERT INTO mms_fts(rowid, body) VALUES(new._id, new.body);\n" +
- "END;");
-
- Log.i(TAG, "Beginning to build search index.");
- long start = SystemClock.elapsedRealtime();
-
- db.execSQL("INSERT INTO sms_fts (rowid, body) SELECT _id, body FROM sms");
-
- long smsFinished = SystemClock.elapsedRealtime();
- Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms");
-
- db.execSQL("INSERT INTO mms_fts (rowid, body) SELECT _id, body FROM mms");
-
- long mmsFinished = SystemClock.elapsedRealtime();
- Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms");
- Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms");
- }
-
- if (oldVersion < BAD_IMPORT_CLEANUP) {
- String trimmedCondition = " NOT IN (SELECT _id FROM mms)";
-
- db.delete("group_receipts", "mms_id" + trimmedCondition, null);
-
- String[] columns = new String[] { "_id", "unique_id", "_data", "thumbnail"};
-
- try (Cursor cursor = db.query("part", columns, "mid" + trimmedCondition, null, null, null, null)) {
- while (cursor != null && cursor.moveToNext()) {
- db.delete("part", "_id = ? AND unique_id = ?", new String[] { String.valueOf(cursor.getLong(0)), String.valueOf(cursor.getLong(1)) });
-
- String data = cursor.getString(2);
- String thumbnail = cursor.getString(3);
-
- if (!TextUtils.isEmpty(data)) {
- new File(data).delete();
- }
-
- if (!TextUtils.isEmpty(thumbnail)) {
- new File(thumbnail).delete();
- }
- }
- }
- }
-
- // Note: This column only being checked due to upgrade issues as described in #8184
- if (oldVersion < QUOTE_MISSING && !columnExists(db, "mms", "quote_missing")) {
- db.execSQL("ALTER TABLE mms ADD COLUMN quote_missing INTEGER DEFAULT 0");
- }
-
- // Note: The column only being checked due to upgrade issues as described in #8184
- if (oldVersion < NOTIFICATION_CHANNELS && !columnExists(db, "recipient_preferences", "notification_channel")) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN notification_channel TEXT DEFAULT NULL");
- NotificationChannels.create(context);
-
- try (Cursor cursor = db.rawQuery("SELECT recipient_ids, system_display_name, signal_profile_name, notification, vibrate FROM recipient_preferences WHERE notification NOT NULL OR vibrate != 0", null)) {
- while (cursor != null && cursor.moveToNext()) {
- String addressString = cursor.getString(cursor.getColumnIndexOrThrow("recipient_ids"));
- Address address = Address.fromExternal(context, addressString);
- String systemName = cursor.getString(cursor.getColumnIndexOrThrow("system_display_name"));
- String profileName = cursor.getString(cursor.getColumnIndexOrThrow("signal_profile_name"));
- String messageSound = cursor.getString(cursor.getColumnIndexOrThrow("notification"));
- Uri messageSoundUri = messageSound != null ? Uri.parse(messageSound) : null;
- int vibrateState = cursor.getInt(cursor.getColumnIndexOrThrow("vibrate"));
- String displayName = NotificationChannels.getChannelDisplayNameFor(context, systemName, profileName, address);
- boolean vibrateEnabled = vibrateState == 0 ? TextSecurePreferences.isNotificationVibrateEnabled(context) : vibrateState == 1;
-
- if (address.isGroup()) {
- try(Cursor groupCursor = db.rawQuery("SELECT title FROM groups WHERE group_id = ?", new String[] { address.toGroupString() })) {
- if (groupCursor != null && groupCursor.moveToFirst()) {
- String title = groupCursor.getString(groupCursor.getColumnIndexOrThrow("title"));
-
- if (!TextUtils.isEmpty(title)) {
- displayName = title;
- }
- }
- }
- }
-
- String channelId = NotificationChannels.createChannelFor(context, address, displayName, messageSoundUri, vibrateEnabled);
-
- ContentValues values = new ContentValues(1);
- values.put("notification_channel", channelId);
- db.update("recipient_preferences", values, "recipient_ids = ?", new String[] { addressString });
- }
- }
- }
-
- if (oldVersion < SECRET_SENDER) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN unidentified_access_mode INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE push ADD COLUMN server_timestamp INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE push ADD COLUMN server_guid TEXT DEFAULT NULL");
- db.execSQL("ALTER TABLE group_receipts ADD COLUMN unidentified INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE mms ADD COLUMN unidentified INTEGER DEFAULT 0");
- db.execSQL("ALTER TABLE sms ADD COLUMN unidentified INTEGER DEFAULT 0");
- }
-
- if (oldVersion < ATTACHMENT_CAPTIONS) {
- db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL");
- }
-
- // 4.30.8 included a migration, but not a correct CREATE_TABLE statement, so we need to add
- // this column if it isn't present.
- if (oldVersion < ATTACHMENT_CAPTIONS_FIX) {
- if (!columnExists(db, "part", "caption")) {
- db.execSQL("ALTER TABLE part ADD COLUMN caption TEXT DEFAULT NULL");
- }
- }
-
- if (oldVersion < PREVIEWS) {
- db.execSQL("ALTER TABLE mms ADD COLUMN previews TEXT");
- }
-
- if (oldVersion < CONVERSATION_SEARCH) {
- db.execSQL("DROP TABLE sms_fts");
- db.execSQL("DROP TABLE mms_fts");
- db.execSQL("DROP TRIGGER sms_ai");
- db.execSQL("DROP TRIGGER sms_au");
- db.execSQL("DROP TRIGGER sms_ad");
- db.execSQL("DROP TRIGGER mms_ai");
- db.execSQL("DROP TRIGGER mms_au");
- db.execSQL("DROP TRIGGER mms_ad");
-
- db.execSQL("CREATE VIRTUAL TABLE sms_fts USING fts5(body, thread_id UNINDEXED, content=sms, content_rowid=_id)");
- db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN\n" +
- " INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n" +
- "END;");
- db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN\n" +
- " INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" +
- "END;\n");
- db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN\n" +
- " INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" +
- " INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id);\n" +
- "END;");
-
- db.execSQL("CREATE VIRTUAL TABLE mms_fts USING fts5(body, thread_id UNINDEXED, content=mms, content_rowid=_id)");
- db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN\n" +
- " INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id);\n" +
- "END;");
- db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN\n" +
- " INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" +
- "END;\n");
- db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN\n" +
- " INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id);\n" +
- " INSERT INTO mms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id);\n" +
- "END;");
-
- Log.i(TAG, "Beginning to build search index.");
- long start = SystemClock.elapsedRealtime();
-
- db.execSQL("INSERT INTO sms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM sms");
-
- long smsFinished = SystemClock.elapsedRealtime();
- Log.i(TAG, "Indexing SMS completed in " + (smsFinished - start) + " ms");
-
- db.execSQL("INSERT INTO mms_fts (rowid, body, thread_id) SELECT _id, body, thread_id FROM mms");
-
- long mmsFinished = SystemClock.elapsedRealtime();
- Log.i(TAG, "Indexing MMS completed in " + (mmsFinished - smsFinished) + " ms");
- Log.i(TAG, "Indexing finished. Total time: " + (mmsFinished - start) + " ms");
- }
-
- if (oldVersion < SELF_ATTACHMENT_CLEANUP) {
- String localNumber = TextSecurePreferences.getLocalNumber(context);
-
- if (!TextUtils.isEmpty(localNumber)) {
- try (Cursor threadCursor = db.rawQuery("SELECT _id FROM thread WHERE recipient_ids = ?", new String[]{ localNumber })) {
- if (threadCursor != null && threadCursor.moveToFirst()) {
- long threadId = threadCursor.getLong(0);
- ContentValues updateValues = new ContentValues(1);
-
- updateValues.put("pending_push", 0);
-
- int count = db.update("part", updateValues, "mid IN (SELECT _id FROM mms WHERE thread_id = ?)", new String[]{ String.valueOf(threadId) });
- Log.i(TAG, "Updated " + count + " self-sent attachments.");
- }
- }
- }
- }
-
- if (oldVersion < RECIPIENT_FORCE_SMS_SELECTION) {
- db.execSQL("ALTER TABLE recipient_preferences ADD COLUMN force_sms_selection INTEGER DEFAULT 0");
- }
-
- if (oldVersion < JOBMANAGER_STRIKES_BACK) {
- db.execSQL("CREATE TABLE job_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "job_spec_id TEXT UNIQUE, " +
- "factory_key TEXT, " +
- "queue_key TEXT, " +
- "create_time INTEGER, " +
- "next_run_attempt_time INTEGER, " +
- "run_attempt INTEGER, " +
- "max_attempts INTEGER, " +
- "max_backoff INTEGER, " +
- "max_instances INTEGER, " +
- "lifespan INTEGER, " +
- "serialized_data TEXT, " +
- "is_running INTEGER)");
-
- db.execSQL("CREATE TABLE constraint_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "job_spec_id TEXT, " +
- "factory_key TEXT, " +
- "UNIQUE(job_spec_id, factory_key))");
-
- db.execSQL("CREATE TABLE dependency_spec(_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "job_spec_id TEXT, " +
- "depends_on_job_spec_id TEXT, " +
- "UNIQUE(job_spec_id, depends_on_job_spec_id))");
- }
-
- if (oldVersion < STICKERS) {
- db.execSQL("CREATE TABLE sticker (_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
- "pack_id TEXT NOT NULL, " +
- "pack_key TEXT NOT NULL, " +
- "pack_title TEXT NOT NULL, " +
- "pack_author TEXT NOT NULL, " +
- "sticker_id INTEGER, " +
- "cover INTEGER, " +
- "emoji TEXT NOT NULL, " +
- "last_used INTEGER, " +
- "installed INTEGER," +
- "file_path TEXT NOT NULL, " +
- "file_length INTEGER, " +
- "file_random BLOB, " +
- "UNIQUE(pack_id, sticker_id, cover) ON CONFLICT IGNORE)");
-
- db.execSQL("CREATE INDEX IF NOT EXISTS sticker_pack_id_index ON sticker (pack_id);");
- db.execSQL("CREATE INDEX IF NOT EXISTS sticker_sticker_id_index ON sticker (sticker_id);");
-
- db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_id TEXT");
- db.execSQL("ALTER TABLE part ADD COLUMN sticker_pack_key TEXT");
- db.execSQL("ALTER TABLE part ADD COLUMN sticker_id INTEGER DEFAULT -1");
- db.execSQL("CREATE INDEX IF NOT EXISTS part_sticker_pack_id_index ON part (sticker_pack_id)");
- }
-
- if (oldVersion < lokiV1) {
- db.execSQL(LokiAPIDatabase.getCreateOpenGroupAuthTokenTableCommand());
- db.execSQL(LokiAPIDatabase.getCreateLastMessageServerIDTableCommand());
- db.execSQL(LokiAPIDatabase.getCreateLastDeletionServerIDTableCommand());
- }
-
- if (oldVersion < lokiV2) {
- db.execSQL(LokiUserDatabase.getCreateServerDisplayNameTableCommand());
- }
-
- if (oldVersion < lokiV3) {
- db.execSQL(LokiAPIDatabase.getCreateDeviceLinkCacheCommand());
- db.execSQL(LokiThreadDatabase.getCreatePublicChatTableCommand());
-
- db.execSQL("ALTER TABLE groups ADD COLUMN avatar_url TEXT");
- db.execSQL("ALTER TABLE part ADD COLUMN url TEXT");
- }
-
- if (oldVersion < lokiV4) {
- db.execSQL(LokiMessageDatabase.getCreateMessageToThreadMappingTableCommand());
- }
-
- if (oldVersion < lokiV5) {
- db.execSQL(LokiAPIDatabase.getCreateUserCountTableCommand());
- }
-
- if (oldVersion < lokiV6) {
- // Migrate public chats from __textsecure_group__ to __loki_public_chat_group__
- try (Cursor lokiPublicChatCursor = db.rawQuery("SELECT public_chat FROM loki_public_chat_database", null)) {
- while (lokiPublicChatCursor != null && lokiPublicChatCursor.moveToNext()) {
- String chatString = lokiPublicChatCursor.getString(0);
- PublicChat publicChat = PublicChat.fromJSON(chatString);
- if (publicChat != null) {
- byte[] groupId = publicChat.getId().getBytes();
- String oldId = GroupUtil.getEncodedId(groupId, false);
- String newId = GroupUtil.getEncodedOpenGroupId(groupId);
- ContentValues threadUpdate = new ContentValues();
- threadUpdate.put("recipient_ids", newId);
- db.update("thread", threadUpdate, "recipient_ids = ?", new String[]{ oldId });
- ContentValues groupUpdate = new ContentValues();
- groupUpdate.put("group_id", newId);
- db.update("groups", groupUpdate,"group_id = ?", new String[] { oldId });
- }
- }
- }
-
- // Migrate RSS feeds from __textsecure_group__ to __loki_rss_feed_group__
- String[] rssFeedIds = new String[] { "loki.network.feed", "loki.network.messenger-updates.feed" };
- for (String groupId : rssFeedIds) {
- String oldId = GroupUtil.getEncodedId(groupId.getBytes(), false);
- String newId = GroupUtil.getEncodedRSSFeedId(groupId.getBytes());
- ContentValues threadUpdate = new ContentValues();
- threadUpdate.put("recipient_ids", newId);
- db.update("thread", threadUpdate, "recipient_ids = ?", new String[]{ oldId });
- ContentValues groupUpdate = new ContentValues();
- groupUpdate.put("group_id", newId);
- db.update("groups", groupUpdate,"group_id = ?", new String[] { oldId });
- }
-
- // Add admin field in groups
- db.execSQL("ALTER TABLE groups ADD COLUMN admins TEXT");
- }
-
if (oldVersion < lokiV7) {
db.execSQL(LokiMessageDatabase.getCreateErrorMessageTableCommand());
}
@@ -652,10 +228,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
} finally {
db.endTransaction();
}
-
- if (oldVersion < MIGRATE_PREKEYS_VERSION) {
-// PreKeyMigrationHelper.cleanUpPreKeys(context);
- }
}
public SQLiteDatabase getReadableDatabase() {
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java
deleted file mode 100644
index ce74ce7e75..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SessionStoreMigrationHelper.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.thoughtcrime.securesms.database.helpers;
-
-
-import android.content.ContentValues;
-import android.content.Context;
-import org.thoughtcrime.securesms.logging.Log;
-
-import net.sqlcipher.database.SQLiteDatabase;
-
-import org.thoughtcrime.securesms.database.Address;
-import org.thoughtcrime.securesms.database.SessionDatabase;
-import org.thoughtcrime.securesms.util.Conversions;
-import org.session.libsignal.libsignal.state.SessionRecord;
-import org.session.libsignal.libsignal.state.SessionState;
-import org.session.libsignal.libsignal.state.StorageProtos.SessionStructure;
-import org.session.libsignal.service.api.push.SignalServiceAddress;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-class SessionStoreMigrationHelper {
-
- private static final String TAG = SessionStoreMigrationHelper.class.getSimpleName();
-
- private static final String SESSIONS_DIRECTORY_V2 = "sessions-v2";
- private static final Object FILE_LOCK = new Object();
-
- private static final int SINGLE_STATE_VERSION = 1;
- private static final int ARCHIVE_STATES_VERSION = 2;
- private static final int PLAINTEXT_VERSION = 3;
- private static final int CURRENT_VERSION = 3;
-
- static void migrateSessions(Context context, SQLiteDatabase database) {
- File directory = new File(context.getFilesDir(), SESSIONS_DIRECTORY_V2);
-
- if (directory.exists()) {
- File[] sessionFiles = directory.listFiles();
-
- if (sessionFiles != null) {
- for (File sessionFile : sessionFiles) {
- try {
- String[] parts = sessionFile.getName().split("[.]");
- Address address = Address.fromSerialized(parts[0]);
-
- int deviceId;
-
- if (parts.length > 1) deviceId = Integer.parseInt(parts[1]);
- else deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID;
-
- FileInputStream in = new FileInputStream(sessionFile);
- int versionMarker = readInteger(in);
-
- if (versionMarker > CURRENT_VERSION) {
- throw new AssertionError("Unknown version: " + versionMarker + ", " + sessionFile.getAbsolutePath());
- }
-
- byte[] serialized = readBlob(in);
- in.close();
-
- if (versionMarker < PLAINTEXT_VERSION) {
- throw new AssertionError("Not plaintext: " + versionMarker + ", " + sessionFile.getAbsolutePath());
- }
-
- SessionRecord sessionRecord;
-
- if (versionMarker == SINGLE_STATE_VERSION) {
- Log.i(TAG, "Migrating single state version: " + sessionFile.getAbsolutePath());
- SessionStructure sessionStructure = SessionStructure.parseFrom(serialized);
- SessionState sessionState = new SessionState(sessionStructure);
-
- sessionRecord = new SessionRecord(sessionState);
- } else if (versionMarker >= ARCHIVE_STATES_VERSION) {
- Log.i(TAG, "Migrating session: " + sessionFile.getAbsolutePath());
- sessionRecord = new SessionRecord(serialized);
- } else {
- throw new AssertionError("Unknown version: " + versionMarker + ", " + sessionFile.getAbsolutePath());
- }
-
-
- ContentValues contentValues = new ContentValues();
- contentValues.put(SessionDatabase.ADDRESS, address.serialize());
- contentValues.put(SessionDatabase.DEVICE, deviceId);
- contentValues.put(SessionDatabase.RECORD, sessionRecord.serialize());
-
- database.insert(SessionDatabase.TABLE_NAME, null, contentValues);
- } catch (NumberFormatException | IOException e) {
- Log.w(TAG, e);
- }
- }
- }
- }
- }
-
- private static byte[] readBlob(FileInputStream in) throws IOException {
- int length = readInteger(in);
- byte[] blobBytes = new byte[length];
-
- in.read(blobBytes, 0, blobBytes.length);
- return blobBytes;
- }
-
- private static int readInteger(FileInputStream in) throws IOException {
- byte[] integer = new byte[4];
- in.read(integer, 0, integer.length);
- return Conversions.byteArrayToInt(integer);
- }
-
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java
index ac1215f6fd..6b2e83b735 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/giph/ui/GiphyActivity.java
@@ -21,7 +21,6 @@ import com.google.android.material.tabs.TabLayout;
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.providers.BlobProvider;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.ViewUtil;
@@ -42,19 +41,12 @@ public class GiphyActivity extends PassphraseRequiredActionBarActivity
public static final String EXTRA_WIDTH = "extra_width";
public static final String EXTRA_HEIGHT = "extra_height";
- private final DynamicLanguage dynamicLanguage = new DynamicLanguage();
-
private GiphyGifFragment gifFragment;
private GiphyStickerFragment stickerFragment;
private boolean forMms;
private GiphyAdapter.GiphyViewHolder finishingImage;
- @Override
- public void onPreCreate() {
- dynamicLanguage.onCreate(this);
- }
-
@Override
public void onCreate(Bundle bundle, boolean ready) {
setContentView(R.layout.giphy_activity);
diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
index e2af735dd5..ecafc01fff 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshAttributesJob.java
@@ -19,6 +19,7 @@ import java.io.IOException;
import javax.inject.Inject;
+//TODO AC: Delete
public class RefreshAttributesJob extends BaseJob implements InjectableType {
public static final String KEY = "RefreshAttributesJob";
diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java
index 2ebc0a9ad2..fbef184b4a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java
@@ -5,17 +5,13 @@ import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
-import androidx.preference.CheckBoxPreference;
import androidx.preference.Preference;
import org.thoughtcrime.securesms.ApplicationContext;
-import org.thoughtcrime.securesms.PassphraseChangeActivity;
import org.thoughtcrime.securesms.components.SwitchPreferenceCompat;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.dependencies.InjectableType;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -27,8 +23,6 @@ import network.loki.messenger.R;
public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment implements InjectableType {
- private CheckBoxPreference disablePassphrase;
-
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
@@ -39,17 +33,12 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
public void onCreate(Bundle paramBundle) {
super.onCreate(paramBundle);
- disablePassphrase = (CheckBoxPreference) this.findPreference("pref_enable_passphrase_temporary");
-
this.findPreference(TextSecurePreferences.SCREEN_LOCK).setOnPreferenceChangeListener(new ScreenLockListener());
this.findPreference(TextSecurePreferences.SCREEN_LOCK_TIMEOUT).setOnPreferenceClickListener(new ScreenLockTimeoutListener());
- this.findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF).setOnPreferenceClickListener(new ChangePassphraseClickListener());
- this.findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF).setOnPreferenceClickListener(new PassphraseIntervalClickListener());
this.findPreference(TextSecurePreferences.READ_RECEIPTS_PREF).setOnPreferenceChangeListener(new ReadReceiptToggleListener());
this.findPreference(TextSecurePreferences.TYPING_INDICATORS).setOnPreferenceChangeListener(new TypingIndicatorsToggleListener());
this.findPreference(TextSecurePreferences.LINK_PREVIEWS).setOnPreferenceChangeListener(new LinkPreviewToggleListener());
- disablePassphrase.setOnPreferenceChangeListener(new DisablePassphraseClickListener());
initializeVisibility();
}
@@ -62,16 +51,9 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
@Override
public void onResume() {
super.onResume();
- if (!TextSecurePreferences.isPasswordDisabled(getContext())) initializePassphraseTimeoutSummary();
- else initializeScreenLockTimeoutSummary();
-
- disablePassphrase.setChecked(!TextSecurePreferences.isPasswordDisabled(getActivity()));
- }
-
- private void initializePassphraseTimeoutSummary() {
- int timeoutMinutes = TextSecurePreferences.getPassphraseTimeoutInterval(getActivity());
- this.findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF)
- .setSummary(getResources().getQuantityString(R.plurals.AppProtectionPreferenceFragment_minutes, timeoutMinutes, timeoutMinutes));
+ if (TextSecurePreferences.isPasswordDisabled(getContext())) {
+ initializeScreenLockTimeoutSummary();
+ }
}
private void initializeScreenLockTimeoutSummary() {
@@ -87,11 +69,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
private void initializeVisibility() {
if (TextSecurePreferences.isPasswordDisabled(getContext())) {
- findPreference("pref_enable_passphrase_temporary").setVisible(false);
- findPreference(TextSecurePreferences.CHANGE_PASSPHRASE_PREF).setVisible(false);
- findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_INTERVAL_PREF).setVisible(false);
- findPreference(TextSecurePreferences.PASSPHRASE_TIMEOUT_PREF).setVisible(false);
-
KeyguardManager keyguardManager = (KeyguardManager)getContext().getSystemService(Context.KEYGUARD_SERVICE);
if (!keyguardManager.isKeyguardSecure()) {
((SwitchPreferenceCompat)findPreference(TextSecurePreferences.SCREEN_LOCK)).setChecked(false);
@@ -178,90 +155,4 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment
return true;
}
}
-
- public static CharSequence getSummary(Context context) {
- final int privacySummaryResId = R.string.ApplicationPreferencesActivity_privacy_summary;
- final String onRes = context.getString(R.string.ApplicationPreferencesActivity_on);
- final String offRes = context.getString(R.string.ApplicationPreferencesActivity_off);
-
- if (TextSecurePreferences.isPasswordDisabled(context) && !TextSecurePreferences.isScreenLockEnabled(context)) {
-// if (TextSecurePreferences.isRegistrationtLockEnabled(context)) {
-// return context.getString(privacySummaryResId, offRes, onRes);
-// } else {
- return context.getString(privacySummaryResId, offRes, offRes);
-// }
- } else {
-// if (TextSecurePreferences.isRegistrationtLockEnabled(context)) {
-// return context.getString(privacySummaryResId, onRes, onRes);
-// } else {
- return context.getString(privacySummaryResId, onRes, offRes);
-// }
- }
- }
-
- private class ChangePassphraseClickListener implements Preference.OnPreferenceClickListener {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- if (MasterSecretUtil.isPassphraseInitialized(getActivity())) {
- startActivity(new Intent(getActivity(), PassphraseChangeActivity.class));
- } else {
- Toast.makeText(getActivity(),
- R.string.ApplicationPreferenceActivity_you_havent_set_a_passphrase_yet,
- Toast.LENGTH_LONG).show();
- }
-
- return true;
- }
- }
-
- private class PassphraseIntervalClickListener implements Preference.OnPreferenceClickListener {
-
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new TimeDurationPickerDialog(getContext(), (view, duration) -> {
- int timeoutMinutes = Math.max((int)TimeUnit.MILLISECONDS.toMinutes(duration), 1);
-
- TextSecurePreferences.setPassphraseTimeoutInterval(getActivity(), timeoutMinutes);
-
- initializePassphraseTimeoutSummary();
-
- }, 0).show();
-
- return true;
- }
- }
-
- private class DisablePassphraseClickListener implements Preference.OnPreferenceChangeListener {
-
- @Override
- public boolean onPreferenceChange(final Preference preference, Object newValue) {
- if (((CheckBoxPreference)preference).isChecked()) {
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setTitle(R.string.ApplicationPreferencesActivity_disable_passphrase);
- builder.setMessage(R.string.ApplicationPreferencesActivity_this_will_permanently_unlock_signal_and_message_notifications);
- builder.setIconAttribute(R.attr.dialog_alert_icon);
- builder.setPositiveButton(R.string.ApplicationPreferencesActivity_disable, (dialog, which) -> {
- MasterSecretUtil.changeMasterSecretPassphrase(getActivity(),
- KeyCachingService.getMasterSecret(getContext()),
- MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
-
- TextSecurePreferences.setPasswordDisabled(getActivity(), true);
- ((CheckBoxPreference)preference).setChecked(false);
-
- Intent intent = new Intent(getActivity(), KeyCachingService.class);
- intent.setAction(KeyCachingService.DISABLE_ACTION);
- getActivity().startService(intent);
-
- initializeVisibility();
- });
- builder.setNegativeButton(android.R.string.cancel, null);
- builder.show();
- } else {
- Intent intent = new Intent(getActivity(), PassphraseChangeActivity.class);
- startActivity(intent);
- }
-
- return false;
- }
- }
}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java
index aae8b49377..911028cd32 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java
@@ -34,13 +34,9 @@ import androidx.core.app.NotificationCompat;
import org.thoughtcrime.securesms.ApplicationContext;
import org.thoughtcrime.securesms.DatabaseUpgradeActivity;
import org.thoughtcrime.securesms.DummyActivity;
-import org.thoughtcrime.securesms.crypto.InvalidPassphraseException;
-import org.thoughtcrime.securesms.crypto.MasterSecret;
-import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.loki.activities.HomeActivity;
import org.thoughtcrime.securesms.notifications.NotificationChannels;
-import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.ServiceUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
@@ -67,13 +63,12 @@ public class KeyCachingService extends Service {
private static final String PASSPHRASE_EXPIRED_EVENT = "org.thoughtcrime.securesms.service.action.PASSPHRASE_EXPIRED_EVENT";
public static final String CLEAR_KEY_ACTION = "org.thoughtcrime.securesms.service.action.CLEAR_KEY";
public static final String DISABLE_ACTION = "org.thoughtcrime.securesms.service.action.DISABLE";
- public static final String LOCALE_CHANGE_EVENT = "org.thoughtcrime.securesms.service.action.LOCALE_CHANGE_EVENT";
-
- private DynamicLanguage dynamicLanguage = new DynamicLanguage();
private final IBinder binder = new KeySetBinder();
- private static MasterSecret masterSecret;
+ // AC: This is a temporal drop off replacement for the refactoring time being.
+ // This field only indicates if the app was unlocked or not (null means locked).
+ private static Object masterSecret;
public KeyCachingService() {}
@@ -81,18 +76,6 @@ public class KeyCachingService extends Service {
return getMasterSecret(context) == null;
}
- public static synchronized @Nullable MasterSecret getMasterSecret(Context context) {
- if (masterSecret == null && (TextSecurePreferences.isPasswordDisabled(context) && !TextSecurePreferences.isScreenLockEnabled(context))) {
- try {
- return MasterSecretUtil.getMasterSecret(context, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
- } catch (InvalidPassphraseException e) {
- Log.w("KeyCachingService", e);
- }
- }
-
- return masterSecret;
- }
-
public static void onAppForegrounded(@NonNull Context context) {
ServiceUtil.getAlarmManager(context).cancel(buildExpirationPendingIntent(context));
}
@@ -101,8 +84,22 @@ public class KeyCachingService extends Service {
startTimeoutIfAppropriate(context);
}
+ //TODO AC: Delete
+ public static synchronized @Nullable Object getMasterSecret(Context context) {
+// if (masterSecret == null && (TextSecurePreferences.isPasswordDisabled(context) && !TextSecurePreferences.isScreenLockEnabled(context))) {
+// try {
+// return MasterSecretUtil.getMasterSecret(context, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
+// } catch (InvalidPassphraseException e) {
+// Log.w("KeyCachingService", e);
+// }
+// }
+
+ return masterSecret;
+ }
+
+ //TODO AC: Delete
@SuppressLint("StaticFieldLeak")
- public void setMasterSecret(final MasterSecret masterSecret) {
+ public void setMasterSecret(final Object masterSecret) {
synchronized (KeyCachingService.class) {
KeyCachingService.masterSecret = masterSecret;
@@ -132,7 +129,6 @@ public class KeyCachingService extends Service {
case CLEAR_KEY_ACTION: handleClearKey(); break;
case PASSPHRASE_EXPIRED_EVENT: handleClearKey(); break;
case DISABLE_ACTION: handleDisableService(); break;
- case LOCALE_CHANGE_EVENT: handleLocaleChanged(); break;
case LOCK_TOGGLED_EVENT: handleLockToggled(); break;
}
}
@@ -146,12 +142,12 @@ public class KeyCachingService extends Service {
super.onCreate();
if (TextSecurePreferences.isPasswordDisabled(this) && !TextSecurePreferences.isScreenLockEnabled(this)) {
- try {
- MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
- setMasterSecret(masterSecret);
- } catch (InvalidPassphraseException e) {
- Log.w("KeyCachingService", e);
- }
+// try {
+// MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
+ setMasterSecret(new Object());
+// } catch (InvalidPassphraseException e) {
+// Log.w("KeyCachingService", e);
+// }
}
}
@@ -196,12 +192,12 @@ public class KeyCachingService extends Service {
private void handleLockToggled() {
stopForeground(true);
- try {
- MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
+// try {
+// MasterSecret masterSecret = MasterSecretUtil.getMasterSecret(this, MasterSecretUtil.UNENCRYPTED_PASSPHRASE);
setMasterSecret(masterSecret);
- } catch (InvalidPassphraseException e) {
- Log.w(TAG, e);
- }
+// } catch (InvalidPassphraseException e) {
+// Log.w(TAG, e);
+// }
}
private void handleDisableService() {
@@ -212,11 +208,6 @@ public class KeyCachingService extends Service {
}
}
- private void handleLocaleChanged() {
- dynamicLanguage.updateServiceLocale(this);
- foregroundService();
- }
-
private static void startTimeoutIfAppropriate(@NonNull Context context) {
boolean appVisible = ApplicationContext.getInstance(context).isAppVisible();
boolean secretSet = KeyCachingService.masterSecret != null;
diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index ff1834e22e..202d901b15 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -136,7 +136,7 @@ public class TextSecurePreferences {
private static final String DATABASE_UNENCRYPTED_SECRET = "pref_database_unencrypted_secret";
private static final String ATTACHMENT_ENCRYPTED_SECRET = "pref_attachment_encrypted_secret";
private static final String ATTACHMENT_UNENCRYPTED_SECRET = "pref_attachment_unencrypted_secret";
- private static final String NEEDS_SQLCIPHER_MIGRATION = "pref_needs_sql_cipher_migration";
+ private static final String NEEDS_SQLCIPHER_MIGRATION = "pref_needs_sql_cipher_migration"; //TODO AC: Delete
private static final String NEXT_PRE_KEY_ID = "pref_next_pre_key_id";
private static final String ACTIVE_SIGNED_PRE_KEY_ID = "pref_active_signed_pre_key_id";
diff --git a/app/src/main/res/layout/change_passphrase_activity.xml b/app/src/main/res/layout/change_passphrase_activity.xml
deleted file mode 100644
index 4dfe1626f0..0000000000
--- a/app/src/main/res/layout/change_passphrase_activity.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/create_passphrase_activity.xml b/app/src/main/res/layout/create_passphrase_activity.xml
deleted file mode 100644
index 43b310aec1..0000000000
--- a/app/src/main/res/layout/create_passphrase_activity.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/prompt_passphrase_activity.xml b/app/src/main/res/layout/prompt_passphrase_activity.xml
index 372a67663b..83f38c2db6 100644
--- a/app/src/main/res/layout/prompt_passphrase_activity.xml
+++ b/app/src/main/res/layout/prompt_passphrase_activity.xml
@@ -73,73 +73,7 @@
android:id="@+id/lock_screen_auth_container"
android:layout_width="196dp"
android:layout_height="@dimen/medium_button_height"
- android:text="Tap to Unlock" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:text="Tap to Unlock"/>
\ No newline at end of file
diff --git a/app/src/main/res/menu/log_submit.xml b/app/src/main/res/menu/log_submit.xml
deleted file mode 100644
index abd321d48d..0000000000
--- a/app/src/main/res/menu/log_submit.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/preferences_app_protection.xml b/app/src/main/res/xml/preferences_app_protection.xml
index ce35f30300..35f9028a5b 100644
--- a/app/src/main/res/xml/preferences_app_protection.xml
+++ b/app/src/main/res/xml/preferences_app_protection.xml
@@ -15,29 +15,29 @@
android:key="pref_android_screen_lock_timeout"
android:dependency="pref_android_screen_lock" />
-
+
+
+
+
+
-
+
+
+
+
+
-
+
+
+
+
+
+
-
+
+
+
+