diff --git a/.gitignore b/.gitignore index c609669e9..1ded40463 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ obj/ jni/libspeex/.deps/ *.sh pkcs11.password +dev.keystore diff --git a/app/build.gradle b/app/build.gradle index 3515e32e5..c1a476d9d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,15 @@ android { javaMaxHeapSize "4g" } + signingConfigs { + staging { + storeFile file("${project.rootDir}/dev.keystore") + storePassword 'android' + keyAlias 'staging' + keyPassword 'android' + } + } + defaultConfig { versionCode canonicalVersionCode * postFixSize versionName canonicalVersionName @@ -195,6 +204,8 @@ android { } staging { initWith debug + applicationIdSuffix ".staging" + signingConfig signingConfigs.staging buildConfigField "String", "SIGNAL_URL", "\"https://textsecure-service-staging.whispersystems.org\"" buildConfigField "String", "STORAGE_URL", "\"https://storage-staging.signal.org\"" diff --git a/app/src/flipper/AndroidManifest.xml b/app/src/flipper/AndroidManifest.xml index 1f15fab86..e2404f13d 100644 --- a/app/src/flipper/AndroidManifest.xml +++ b/app/src/flipper/AndroidManifest.xml @@ -5,5 +5,12 @@ + tools:replace="android:name"> + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 298775a11..4bf47a912 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,7 @@ - @@ -113,7 +113,7 @@ - + android:value=".MainActivity" /> - + @@ -650,15 +650,15 @@ + android:authorities="${applicationId}.part" /> + android:authorities="${applicationId}.mms" /> @@ -667,23 +667,23 @@ diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseContentProviders.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseContentProviders.java index da62f5fd2..ed22c13cc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseContentProviders.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseContentProviders.java @@ -4,9 +4,12 @@ import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.thoughtcrime.securesms.BuildConfig; + /** * Starting in API 26, a {@link ContentProvider} needs to be defined for each authority you wish to * observe changes on. These classes essentially do nothing except exist so Android doesn't complain. @@ -14,11 +17,15 @@ import androidx.annotation.Nullable; public class DatabaseContentProviders { public static class ConversationList extends NoopContentProvider { - public static final Uri CONTENT_URI = Uri.parse("content://org.thoughtcrime.securesms.database.conversationlist"); + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".database.conversationlist"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY; + + public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); } public static class Conversation extends NoopContentProvider { - private static final String CONTENT_URI_STRING = "content://org.thoughtcrime.securesms.database.conversation/"; + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".database.conversation"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY + "/"; public static Uri getUriForThread(long threadId) { return Uri.parse(CONTENT_URI_STRING + threadId); @@ -34,15 +41,24 @@ public class DatabaseContentProviders { } public static class Attachment extends NoopContentProvider { - public static final Uri CONTENT_URI = Uri.parse("content://org.thoughtcrime.securesms.database.attachment"); + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".database.attachment"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY; + + public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); } public static class Sticker extends NoopContentProvider { - public static final Uri CONTENT_URI = Uri.parse("content://org.thoughtcrime.securesms.database.sticker"); + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".database.sticker"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY; + + public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); } public static class StickerPack extends NoopContentProvider { - public static final Uri CONTENT_URI = Uri.parse("content://org.thoughtcrime.securesms.database.stickerpack"); + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".database.stickerpack"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY; + + public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); } private static abstract class NoopContentProvider extends ContentProvider { diff --git a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPermissions.java b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPermissions.java index 873da276b..e147f793c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPermissions.java +++ b/app/src/main/java/org/thoughtcrime/securesms/logsubmit/LogSectionPermissions.java @@ -6,6 +6,7 @@ import android.content.pm.PackageManager; import androidx.annotation.NonNull; +import org.thoughtcrime.securesms.BuildConfig; import org.whispersystems.libsignal.util.Pair; import java.util.ArrayList; @@ -24,7 +25,7 @@ public class LogSectionPermissions implements LogSection { List> status = new ArrayList<>(); try { - PackageInfo info = context.getPackageManager().getPackageInfo("org.thoughtcrime.securesms", PackageManager.GET_PERMISSIONS); + PackageInfo info = context.getPackageManager().getPackageInfo(BuildConfig.APPLICATION_ID, PackageManager.GET_PERMISSIONS); for (int i = 0; i < info.requestedPermissions.length; i++) { status.add(new Pair<>(info.requestedPermissions[i], diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java index 11f57e8f6..daf19ab7e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PartAuthority.java @@ -4,25 +4,26 @@ import android.content.ContentUris; import android.content.Context; import android.content.UriMatcher; import android.net.Uri; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; -import org.thoughtcrime.securesms.blurhash.BlurHash; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.DeprecatedPersistentBlobProvider; import org.thoughtcrime.securesms.providers.PartProvider; -import org.thoughtcrime.securesms.util.MediaUtil; import java.io.IOException; import java.io.InputStream; public class PartAuthority { - private static final String PART_URI_STRING = "content://org.thoughtcrime.securesms/part"; - private static final String STICKER_URI_STRING = "content://org.thoughtcrime.securesms/sticker"; + private static final String AUTHORITY = BuildConfig.APPLICATION_ID; + private static final String PART_URI_STRING = "content://" + AUTHORITY + "/part"; + private static final String STICKER_URI_STRING = "content://" + AUTHORITY + "/sticker"; private static final Uri PART_CONTENT_URI = Uri.parse(PART_URI_STRING); private static final Uri STICKER_CONTENT_URI = Uri.parse(STICKER_URI_STRING); @@ -35,8 +36,8 @@ public class PartAuthority { static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - uriMatcher.addURI("org.thoughtcrime.securesms", "part/*/#", PART_ROW); - uriMatcher.addURI("org.thoughtcrime.securesms", "sticker/#", STICKER_ROW); + uriMatcher.addURI(AUTHORITY, "part/*/#", PART_ROW); + uriMatcher.addURI(AUTHORITY, "sticker/#", STICKER_ROW); uriMatcher.addURI(DeprecatedPersistentBlobProvider.AUTHORITY, DeprecatedPersistentBlobProvider.EXPECTED_PATH_OLD, PERSISTENT_ROW); uriMatcher.addURI(DeprecatedPersistentBlobProvider.AUTHORITY, DeprecatedPersistentBlobProvider.EXPECTED_PATH_NEW, PERSISTENT_ROW); uriMatcher.addURI(BlobProvider.AUTHORITY, BlobProvider.PATH, BLOB_ROW); diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java index e00a0c372..bb1eea230 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/BlobProvider.java @@ -5,12 +5,14 @@ import android.content.Context; import android.content.UriMatcher; import android.media.MediaDataSource; import android.net.Uri; + import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; @@ -43,9 +45,9 @@ public class BlobProvider { private static final String MULTI_SESSION_DIRECTORY = "multi_session_blobs"; private static final String SINGLE_SESSION_DIRECTORY = "single_session_blobs"; - public static final Uri CONTENT_URI = Uri.parse("content://org.thoughtcrime.securesms/blob"); - public static final String AUTHORITY = "org.thoughtcrime.securesms"; - public static final String PATH = "blob/*/*/*/*/*"; + public static final String AUTHORITY = BuildConfig.APPLICATION_ID; + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/blob"); + public static final String PATH = "blob/*/*/*/*/*"; private static final int STORAGE_TYPE_PATH_SEGMENT = 1; private static final int MIMETYPE_PATH_SEGMENT = 2; diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/DeprecatedPersistentBlobProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/DeprecatedPersistentBlobProvider.java index 3c663daaa..1703dff55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/DeprecatedPersistentBlobProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/DeprecatedPersistentBlobProvider.java @@ -4,16 +4,17 @@ import android.content.ContentUris; import android.content.Context; import android.content.UriMatcher; import android.net.Uri; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import org.thoughtcrime.securesms.logging.Log; - import android.webkit.MimeTypeMap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.AttachmentSecretProvider; import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; +import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.util.FileProviderUtil; import java.io.File; @@ -29,11 +30,11 @@ import java.io.InputStream; @Deprecated public class DeprecatedPersistentBlobProvider { - private static final String TAG = DeprecatedPersistentBlobProvider.class.getSimpleName(); + private static final String TAG = Log.tag(DeprecatedPersistentBlobProvider.class); - private static final String URI_STRING = "content://org.thoughtcrime.securesms/capture-new"; + public static final String AUTHORITY = BuildConfig.APPLICATION_ID; + private static final String URI_STRING = "content://" + AUTHORITY + "/capture-new"; public static final Uri CONTENT_URI = Uri.parse(URI_STRING); - public static final String AUTHORITY = "org.thoughtcrime.securesms"; public static final String EXPECTED_PATH_OLD = "capture/*/*/#"; public static final String EXPECTED_PATH_NEW = "capture-new/*/*/*/*/#"; diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/MmsBodyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/MmsBodyProvider.java index 3bf0a22a4..cc98728ee 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/MmsBodyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/MmsBodyProvider.java @@ -24,8 +24,10 @@ import android.content.UriMatcher; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; + import androidx.annotation.NonNull; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.logging.Log; import java.io.File; @@ -35,7 +37,8 @@ import java.io.OutputStream; public class MmsBodyProvider extends ContentProvider { private static final String TAG = MmsBodyProvider.class.getSimpleName(); - private static final String CONTENT_URI_STRING = "content://org.thoughtcrime.provider.securesms.mms/mms"; + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".mms"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY + "/mms"; public static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); private static final int SINGLE_ROW = 1; @@ -43,7 +46,7 @@ public class MmsBodyProvider extends ContentProvider { static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - uriMatcher.addURI("org.thoughtcrime.provider.securesms.mms", "mms/#", SINGLE_ROW); + uriMatcher.addURI(CONTENT_AUTHORITY, "mms/#", SINGLE_ROW); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java index d608648ec..2c9aafd35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/providers/PartProvider.java @@ -26,12 +26,14 @@ import android.net.Uri; import android.os.MemoryFile; import android.os.ParcelFileDescriptor; import android.provider.OpenableColumns; -import androidx.annotation.NonNull; -import org.thoughtcrime.securesms.logging.Log; +import androidx.annotation.NonNull; + +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; import org.thoughtcrime.securesms.database.DatabaseFactory; +import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.mms.PartUriParser; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.MemoryFileUtil; @@ -46,7 +48,8 @@ public class PartProvider extends ContentProvider { private static final String TAG = PartProvider.class.getSimpleName(); - private static final String CONTENT_URI_STRING = "content://org.thoughtcrime.provider.securesms/part"; + private static final String CONTENT_AUTHORITY = BuildConfig.APPLICATION_ID + ".part"; + private static final String CONTENT_URI_STRING = "content://" + CONTENT_AUTHORITY + "/part"; private static final Uri CONTENT_URI = Uri.parse(CONTENT_URI_STRING); private static final int SINGLE_ROW = 1; @@ -54,7 +57,7 @@ public class PartProvider extends ContentProvider { static { uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); - uriMatcher.addURI("org.thoughtcrime.provider.securesms", "part/*/#", SINGLE_ROW); + uriMatcher.addURI(CONTENT_AUTHORITY, "part/*/#", SINGLE_ROW); } @Override 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 c450efc04..ab8adcca6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/KeyCachingService.java @@ -32,6 +32,7 @@ import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; import org.thoughtcrime.securesms.ApplicationContext; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.MainActivity; import org.thoughtcrime.securesms.dependencies.ApplicationDependencies; import org.thoughtcrime.securesms.logging.Log; @@ -61,14 +62,14 @@ public class KeyCachingService extends Service { public static final int SERVICE_RUNNING_ID = 4141; - public static final String KEY_PERMISSION = "org.thoughtcrime.securesms.ACCESS_SECRETS"; - public static final String NEW_KEY_EVENT = "org.thoughtcrime.securesms.service.action.NEW_KEY_EVENT"; - public static final String CLEAR_KEY_EVENT = "org.thoughtcrime.securesms.service.action.CLEAR_KEY_EVENT"; - public static final String LOCK_TOGGLED_EVENT = "org.thoughtcrime.securesms.service.action.LOCK_ENABLED_EVENT"; - 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"; + public static final String KEY_PERMISSION = BuildConfig.APPLICATION_ID + ".ACCESS_SECRETS"; + public static final String NEW_KEY_EVENT = BuildConfig.APPLICATION_ID + ".service.action.NEW_KEY_EVENT"; + public static final String CLEAR_KEY_EVENT = BuildConfig.APPLICATION_ID + ".service.action.CLEAR_KEY_EVENT"; + public static final String LOCK_TOGGLED_EVENT = BuildConfig.APPLICATION_ID + ".service.action.LOCK_ENABLED_EVENT"; + private static final String PASSPHRASE_EXPIRED_EVENT = BuildConfig.APPLICATION_ID + ".service.action.PASSPHRASE_EXPIRED_EVENT"; + public static final String CLEAR_KEY_ACTION = BuildConfig.APPLICATION_ID + ".service.action.CLEAR_KEY"; + public static final String DISABLE_ACTION = BuildConfig.APPLICATION_ID + ".service.action.DISABLE"; + public static final String LOCALE_CHANGE_EVENT = BuildConfig.APPLICATION_ID + ".service.action.LOCALE_CHANGE_EVENT"; private DynamicLanguage dynamicLanguage = new DynamicLanguage(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/FileProviderUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/FileProviderUtil.java index 44de0078d..12359673c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/FileProviderUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/FileProviderUtil.java @@ -7,11 +7,13 @@ import android.os.Build; import androidx.annotation.NonNull; import androidx.core.content.FileProvider; +import org.thoughtcrime.securesms.BuildConfig; + import java.io.File; public class FileProviderUtil { - private static final String AUTHORITY = "org.thoughtcrime.securesms.fileprovider"; + private static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".fileprovider"; public static Uri getUriFor(@NonNull Context context, @NonNull File file) { if (Build.VERSION.SDK_INT >= 24) return FileProvider.getUriForFile(context, AUTHORITY, file); diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/StorageUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/StorageUtil.java index 52e7ab93c..77c7c2859 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/StorageUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/StorageUtil.java @@ -2,14 +2,18 @@ package org.thoughtcrime.securesms.util; import android.content.Context; import android.os.Environment; + import androidx.annotation.Nullable; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.database.NoExternalStorageException; import java.io.File; public class StorageUtil { + private static final String PRODUCTION_PACKAGE_ID = "org.thoughtcrime.securesms"; + public static File getBackupDirectory() throws NoExternalStorageException { File storage = Environment.getExternalStorageDirectory(); @@ -20,6 +24,11 @@ public class StorageUtil { File signal = new File(storage, "Signal"); File backups = new File(signal, "Backups"); + //noinspection ConstantConditions + if (BuildConfig.APPLICATION_ID.startsWith(PRODUCTION_PACKAGE_ID + ".")) { + backups = new File(backups, BuildConfig.APPLICATION_ID.substring(PRODUCTION_PACKAGE_ID.length() + 1)); + } + if (!backups.exists()) { if (!backups.mkdirs()) { throw new NoExternalStorageException("Unable to create backup directory..."); diff --git a/app/src/main/res/layout/conversation_list_fragment.xml b/app/src/main/res/layout/conversation_list_fragment.xml index e13cb899d..dc57cb932 100644 --- a/app/src/main/res/layout/conversation_list_fragment.xml +++ b/app/src/main/res/layout/conversation_list_fragment.xml @@ -183,7 +183,7 @@ + app:layout_behavior="org.thoughtcrime.securesms.util.views.SlideUpWithSnackbarBehavior"> + app:layout_behavior="org.thoughtcrime.securesms.recipients.ui.RecipientSettingsCoordinatorLayoutBehavior" /> + app:layout_behavior="org.thoughtcrime.securesms.recipients.ui.RecipientSettingsCoordinatorLayoutBehavior" /> + + + + \ No newline at end of file diff --git a/app/src/staging/res/xml/authenticator.xml b/app/src/staging/res/xml/authenticator.xml new file mode 100644 index 000000000..58d5d8f68 --- /dev/null +++ b/app/src/staging/res/xml/authenticator.xml @@ -0,0 +1,6 @@ + + diff --git a/app/src/staging/res/xml/syncadapter.xml b/app/src/staging/res/xml/syncadapter.xml new file mode 100644 index 000000000..9e369a00a --- /dev/null +++ b/app/src/staging/res/xml/syncadapter.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file