From 55523b3baf4e4e8b551b5a44759f4f2fde2e5bcb Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 25 Feb 2020 11:28:56 +1100 Subject: [PATCH 01/13] Added open group syncing. Refactor open group adding code. --- .../SignalCommunicationModule.java | 4 +- .../securesms/jobs/JobManagerFactories.java | 2 + .../securesms/jobs/PushDecryptJob.java | 22 +++++ .../loki/MultiDeviceOpenGroupUpdateJob.kt | 83 +++++++++++++++++++ .../securesms/loki/OpenGroupUtilities.kt | 39 +++++++++ .../activities/JoinPublicChatActivity.kt | 22 ++--- .../activities/LinkedDevicesActivity.kt | 1 + .../securesms/sms/MessageSender.java | 5 ++ .../securesms/util/GroupUtil.java | 8 +- 9 files changed, 166 insertions(+), 20 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt create mode 100644 src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt diff --git a/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java b/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java index c59224d481..66a4943088 100644 --- a/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java +++ b/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java @@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation; +import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob; import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob; import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; import org.thoughtcrime.securesms.push.MessageSenderEventListener; @@ -115,7 +116,8 @@ import network.loki.messenger.BuildConfig; MultiDeviceStickerPackOperationJob.class, MultiDeviceStickerPackSyncJob.class, LinkPreviewRepository.class, - PushMessageSyncSendJob.class}) + PushMessageSyncSendJob.class, + MultiDeviceOpenGroupUpdateJob.class}) public class SignalCommunicationModule { diff --git a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index cfa9aa7beb..9911b53514 100644 --- a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver; import org.thoughtcrime.securesms.jobmanager.impl.NetworkOrCellServiceConstraint; import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraint; import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintObserver; +import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob; import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob; import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob; @@ -74,6 +75,7 @@ public final class JobManagerFactories { put(UpdateApkJob.KEY, new UpdateApkJob.Factory()); put(PushMessageSyncSendJob.KEY, new PushMessageSyncSendJob.Factory()); put(PushBackgroundMessageSendJob.KEY, new PushBackgroundMessageSendJob.Factory()); + put(MultiDeviceOpenGroupUpdateJob.KEY, new MultiDeviceOpenGroupUpdateJob.Factory()); }}; } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 6d7595b9b8..efca0e5e3a 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -59,6 +59,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.dependencies.InjectableType; +import org.thoughtcrime.securesms.groups.GroupManager; import org.thoughtcrime.securesms.groups.GroupMessageProcessor; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; @@ -72,6 +73,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation; import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; +import org.thoughtcrime.securesms.loki.OpenGroupUtilities; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase; @@ -138,6 +140,7 @@ import org.whispersystems.signalservice.loki.api.DeviceLink; import org.whispersystems.signalservice.loki.api.DeviceLinkingSession; import org.whispersystems.signalservice.loki.api.LokiAPI; import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; +import org.whispersystems.signalservice.loki.api.LokiPublicChat; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage; @@ -393,6 +396,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get()); else if (syncMessage.getContacts().isPresent()) handleContactSyncMessage(syncMessage.getContacts().get()); else if (syncMessage.getGroups().isPresent()) handleGroupSyncMessage(content, syncMessage.getGroups().get()); + else if (syncMessage.getOpenGroups().isPresent()) handleOpenGroupSyncMessage(syncMessage.getOpenGroups().get()); else Log.w(TAG, "Contains no known sync types..."); } else if (content.getCallMessage().isPresent()) { Log.i(TAG, "Got call message..."); @@ -749,6 +753,24 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } + private void handleOpenGroupSyncMessage(@NonNull List openGroups) { + try { + for (LokiPublicChat openGroup : openGroups) { + long threadID = GroupManager.getPublicChatThreadId(openGroup.getId(), context); + if (threadID > -1) continue; + + String url = openGroup.getServer(); + long channel = openGroup.getChannel(); + OpenGroupUtilities.addGroup(context, url, channel).fail(e -> { + Log.d("Loki", "Failed to sync open group " + url + " due to error: " + e + "."); + return Unit.INSTANCE; + }); + } + } catch (Exception e) { + Log.d("Loki", "Failed to sync open groups due to error: " + e + "."); + } + } + private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content, @NonNull SentTranscriptMessage message) throws StorageFailedException diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt new file mode 100644 index 0000000000..38ee04790b --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt @@ -0,0 +1,83 @@ +package org.thoughtcrime.securesms.loki + +import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil +import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.dependencies.InjectableType +import org.thoughtcrime.securesms.groups.GroupManager +import org.thoughtcrime.securesms.jobmanager.Data +import org.thoughtcrime.securesms.jobmanager.Job +import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint +import org.thoughtcrime.securesms.jobs.BaseJob +import org.thoughtcrime.securesms.logging.Log +import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.whispersystems.signalservice.api.SignalServiceMessageSender +import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage +import org.whispersystems.signalservice.loki.api.LokiPublicChat +import java.util.concurrent.TimeUnit +import javax.inject.Inject + +class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType { + companion object { + const val KEY = "MultiDeviceGroupUpdateJob" + private val TAG = MultiDeviceOpenGroupUpdateJob::class.java.simpleName + } + + @Inject + lateinit var messageSender: SignalServiceMessageSender + + constructor() : this(Parameters.Builder() + .addConstraint(NetworkConstraint.KEY) + .setQueue("MultiDeviceGroupUpdateJob") + .setLifespan(TimeUnit.DAYS.toMillis(1)) + .setMaxAttempts(Parameters.UNLIMITED) + .build()) + + override fun getFactoryKey(): String { + return KEY + } + + override fun serialize(): Data { + return Data.EMPTY + } + + @Throws(Exception::class) + public override fun onRun() { + if (!TextSecurePreferences.isMultiDevice(context)) { + Log.i(TAG, "Not multi device, aborting...") + return + } + + val openGroups = mutableListOf() + DatabaseFactory.getGroupDatabase(context).groups.use { reader -> + while (true) { + val record = reader.next ?: return@use + if (!record.isPublicChat) { continue; } + + val threadID = GroupManager.getThreadIdFromGroupId(record.encodedId, context) + val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) + if (openGroup != null) { + openGroups.add(openGroup) + } + } + } + + if (openGroups.size > 0) { + messageSender.sendMessage(0, SignalServiceSyncMessage.forOpenGroups(openGroups), + UnidentifiedAccessUtil.getAccessForSync(context)) + } else { + Log.d(TAG, "No open groups to sync.") + } + } + + public override fun onShouldRetry(exception: Exception): Boolean { + return false + } + + override fun onCanceled() { } + + class Factory : Job.Factory { + override fun create(parameters: Parameters, data: Data): MultiDeviceOpenGroupUpdateJob { + return MultiDeviceOpenGroupUpdateJob(parameters) + } + } +} diff --git a/src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt b/src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt new file mode 100644 index 0000000000..ae47fb25da --- /dev/null +++ b/src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt @@ -0,0 +1,39 @@ +package org.thoughtcrime.securesms.loki + +import android.content.Context +import nl.komponents.kovenant.Promise +import nl.komponents.kovenant.then +import org.thoughtcrime.securesms.ApplicationContext +import org.thoughtcrime.securesms.crypto.ProfileKeyUtil +import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.groups.GroupManager +import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.whispersystems.signalservice.loki.api.LokiPublicChat + +object OpenGroupUtilities { + @JvmStatic fun addGroup(context: Context, url: String, channel: Long): Promise { + // Check if we have an existing group + val groupId = LokiPublicChat.getId(channel, url) + val threadID = GroupManager.getPublicChatThreadId(groupId, context) + val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) + if (openGroup != null) { + return Promise.of(openGroup) + } + + // Add the new group + val application = ApplicationContext.getInstance(context) + val displayName = TextSecurePreferences.getProfileName(context) + val lokiPublicChatAPI = application.lokiPublicChatAPI ?: throw Error("LokiPublicChatAPI is not initialized") + return application.lokiPublicChatManager.addChat(url, channel).then { group -> + DatabaseFactory.getLokiAPIDatabase(context).removeLastMessageServerID(channel, url) + DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(channel, url) + lokiPublicChatAPI.getMessages(channel, url) + lokiPublicChatAPI.setDisplayName(displayName, url) + lokiPublicChatAPI.join(channel, url) + val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(context) + val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(context) + lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl) + group + } + } +} \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt index 6d3b940378..a7f4b69bc7 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt @@ -16,14 +16,12 @@ import kotlinx.android.synthetic.main.fragment_enter_chat_url.* import network.loki.messenger.R import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi -import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity -import org.thoughtcrime.securesms.crypto.ProfileKeyUtil -import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.loki.OpenGroupUtilities import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate -import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.thoughtcrime.securesms.sms.MessageSender class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate { private val adapter = JoinPublicChatActivityAdapter(this) @@ -68,19 +66,11 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode return Toast.makeText(this, "Invalid URL", Toast.LENGTH_SHORT).show() } showLoader() - val application = ApplicationContext.getInstance(this) + val channel: Long = 1 - val displayName = TextSecurePreferences.getProfileName(this) - val lokiPublicChatAPI = application.lokiPublicChatAPI!! - application.lokiPublicChatManager.addChat(url, channel).successUi { - DatabaseFactory.getLokiAPIDatabase(this).removeLastMessageServerID(channel, url) - DatabaseFactory.getLokiAPIDatabase(this).removeLastDeletionServerID(channel, url) - lokiPublicChatAPI.getMessages(channel, url) - lokiPublicChatAPI.setDisplayName(displayName, url) - lokiPublicChatAPI.join(channel, url) - val profileKey: ByteArray = ProfileKeyUtil.getProfileKey(this) - val profileUrl: String? = TextSecurePreferences.getProfileAvatarUrl(this) - lokiPublicChatAPI.setProfilePicture(url, profileKey, profileUrl) + OpenGroupUtilities.addGroup(this, url, channel).success { + MessageSender.syncAllOpenGroups(this) + }.successUi { finish() }.failUi { hideLoader() diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index 759362b91c..2fae3f0914 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -151,6 +151,7 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager Timer().schedule(4000) { MessageSender.syncAllGroups(this@LinkedDevicesActivity) MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey)) + MessageSender.syncAllOpenGroups(this@LinkedDevicesActivity) } }.failUi { Toast.makeText(this, "Couldn't link device", Toast.LENGTH_LONG).show() diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 80a4baa482..7a72ac68d2 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.BackgroundMessage; import org.thoughtcrime.securesms.loki.FriendRequestHandler; import org.thoughtcrime.securesms.loki.GeneralUtilitiesKt; +import org.thoughtcrime.securesms.loki.MultiDeviceOpenGroupUpdateJob; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.PushBackgroundMessageSendJob; import org.thoughtcrime.securesms.loki.PushMessageSyncSendJob; @@ -86,6 +87,10 @@ public class MessageSender { ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceGroupUpdateJob()); } + public static void syncAllOpenGroups(Context context) { + ApplicationContext.getInstance(context).getJobManager().add(new MultiDeviceOpenGroupUpdateJob()); + } + /** * Send a contact sync message to all our devices telling them that we want to sync `contact` */ diff --git a/src/org/thoughtcrime/securesms/util/GroupUtil.java b/src/org/thoughtcrime/securesms/util/GroupUtil.java index d4bdffa291..0e869da787 100644 --- a/src/org/thoughtcrime/securesms/util/GroupUtil.java +++ b/src/org/thoughtcrime/securesms/util/GroupUtil.java @@ -4,15 +4,13 @@ import android.content.Context; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; -import android.widget.Toast; import com.google.protobuf.ByteString; -import network.loki.messenger.R; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.GroupDatabase.*; +import org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; import org.thoughtcrime.securesms.recipients.Recipient; @@ -26,6 +24,8 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; +import network.loki.messenger.R; + import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; public class GroupUtil { @@ -114,6 +114,8 @@ public class GroupUtil { } public static boolean leaveGroup(@NonNull Context context, Recipient groupRecipient) { + if (!groupRecipient.getAddress().isSignalGroup()) { return true; } + long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(groupRecipient); Optional leaveMessage = GroupUtil.createGroupLeaveMessage(context, groupRecipient); From 7b267ee8b703fb35f40df16b3083e9ef6f3a7da7 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 25 Feb 2020 13:05:50 +1100 Subject: [PATCH 02/13] Fix isSignalGroup boolean check. Set thread deletion delay to 1s for private chats and open groups. --- src/org/thoughtcrime/securesms/database/Address.java | 2 +- .../loki/redesign/activities/HomeActivity.kt | 11 ++++++----- src/org/thoughtcrime/securesms/util/GroupUtil.java | 4 ++++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/org/thoughtcrime/securesms/database/Address.java b/src/org/thoughtcrime/securesms/database/Address.java index 1286b4b302..7cf4f221d5 100644 --- a/src/org/thoughtcrime/securesms/database/Address.java +++ b/src/org/thoughtcrime/securesms/database/Address.java @@ -111,7 +111,7 @@ public class Address implements Parcelable, Comparable
{ public boolean isGroup() { return GroupUtil.isEncodedGroup(address); } - public boolean isSignalGroup() { return !isPublicChat() && !isRSSFeed(); } + public boolean isSignalGroup() { return GroupUtil.isSignalGroup(address); } public boolean isPublicChat() { return GroupUtil.isPublicChat(address); } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt index 3993a93f10..44812f438d 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/HomeActivity.kt @@ -194,7 +194,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe private fun openConversation(thread: ThreadRecord) { val intent = Intent(this, ConversationActivity::class.java) - intent.putExtra(ConversationActivity.ADDRESS_EXTRA, thread.recipient.getAddress()) + intent.putExtra(ConversationActivity.ADDRESS_EXTRA, thread.recipient.address) intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, thread.threadId) intent.putExtra(ConversationActivity.DISTRIBUTION_TYPE_EXTRA, thread.distributionType) intent.putExtra(ConversationActivity.TIMING_EXTRA, System.currentTimeMillis()) @@ -255,9 +255,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe val dialog = AlertDialog.Builder(activity) dialog.setMessage(dialogMessage) dialog.setPositiveButton(R.string.yes) { _, _ -> - val isGroup = recipient.isGroupRecipient + val isClosedGroup = recipient.address.isSignalGroup // Send a leave group message if this is an active closed group - if (isGroup && DatabaseFactory.getGroupDatabase(activity).isActive(recipient.address.toGroupString())) { + if (isClosedGroup && DatabaseFactory.getGroupDatabase(activity).isActive(recipient.address.toGroupString())) { if (!GroupUtil.leaveGroup(activity, recipient)) { Toast.makeText(activity, "Couldn't leave group", Toast.LENGTH_LONG).show() clearView(activity.recyclerView, viewHolder) @@ -267,10 +267,11 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe // Archive the conversation and then delete it after 10 seconds (the case where the // app was closed before the conversation could be deleted is handled in onCreate) threadDatabase.archiveConversation(threadID) + val delay = if (isClosedGroup) 10000L else 1000L val handler = Handler() - handler.postDelayed(deleteThread, 10000) + handler.postDelayed(deleteThread, delay) // Notify the user - val toastMessage = if (isGroup) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message + val toastMessage = if (recipient.isGroupRecipient) R.string.MessageRecord_left_group else R.string.activity_home_conversation_deleted_message Toast.makeText(activity, toastMessage, Toast.LENGTH_LONG).show() } dialog.setNegativeButton(R.string.no) { _, _ -> diff --git a/src/org/thoughtcrime/securesms/util/GroupUtil.java b/src/org/thoughtcrime/securesms/util/GroupUtil.java index 0e869da787..907a21217e 100644 --- a/src/org/thoughtcrime/securesms/util/GroupUtil.java +++ b/src/org/thoughtcrime/securesms/util/GroupUtil.java @@ -87,6 +87,10 @@ public class GroupUtil { return groupId.startsWith(ENCODED_RSS_FEED_GROUP_PREFIX); } + public static boolean isSignalGroup(@NonNull String groupId) { + return groupId.startsWith(ENCODED_SIGNAL_GROUP_PREFIX); + } + @WorkerThread public static Optional createGroupLeaveMessage(@NonNull Context context, @NonNull Recipient groupRecipient) { String encodedGroupId = groupRecipient.getAddress().toGroupString(); From c3ab7e0d12ecff8b67cf5d7066e62516023b9525 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 25 Feb 2020 09:30:23 +0700 Subject: [PATCH 03/13] Update version number --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index f7dcc19354..6a0b002293 100644 --- a/build.gradle +++ b/build.gradle @@ -199,8 +199,8 @@ dependencies { implementation "com.github.ybq:Android-SpinKit:1.4.0" } -def canonicalVersionCode = 36 -def canonicalVersionName = "1.0.2" +def canonicalVersionCode = 37 +def canonicalVersionName = "1.0.3" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, From 85b23795103cbb86df88adc14f31a778b49901df Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 26 Feb 2020 11:53:28 +1100 Subject: [PATCH 04/13] Fix race condition that occurs on device link authorisation. Upon authorisation, we upload our mapping to the server. At the same time we also get a contact sync message and send out background friend request messages. There was a race condition between those 2 functions where to correctly establish multi-device communication, you need your mapping on the server so that the other party knows that it's a secondary device and not a regular user. --- .../thoughtcrime/securesms/ApplicationContext.java | 3 +++ .../securesms/jobs/PushDecryptJob.java | 14 +++++++++++++- .../securesms/loki/MultiDeviceUtilities.kt | 6 ++++++ .../loki/redesign/activities/LandingActivity.kt | 1 - 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index f8eed2a13d..1661754ebb 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -194,6 +194,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc if (userHexEncodedPublicKey != null) { if (TextSecurePreferences.getNeedsIsRevokedSlaveDeviceCheck(this)) { MultiDeviceUtilities.checkIsRevokedSlaveDevice(this); + } else { + // We always update our current device links onto the server in case we failed to do so upon linking + MultiDeviceUtilities.updateDeviceLinksOnServer(this); } } } diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 6d7595b9b8..d85fe7b720 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -138,6 +138,7 @@ import org.whispersystems.signalservice.loki.api.DeviceLink; import org.whispersystems.signalservice.loki.api.DeviceLinkingSession; import org.whispersystems.signalservice.loki.api.LokiAPI; import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage; @@ -704,6 +705,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient); LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID); if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) { + // TODO: We should ensure that our mapping has been uploaded to the server before sending out this message MessageSender.sendBackgroundFriendRequest(context, hexEncodedPublicKey, "Please accept to enable messages to be synced across devices"); Log.d("Loki", "Sent friend request to " + hexEncodedPublicKey); } else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) { @@ -1206,6 +1208,17 @@ public class PushDecryptJob extends BaseJob implements InjectableType { TextSecurePreferences.setMultiDevice(context, true); // Send a background message to the master device MessageSender.sendBackgroundMessage(context, deviceLink.getMasterHexEncodedPublicKey()); + /* + Update device link on the file server. + We put this here because after receiving the authorisation message, we will also receive all sync messages. + If these sync messages are contact syncs then we need to send them friend requests so that we can establish multi-device communication. + If our device mapping is not stored on the server before the other party receives our message, they will think that they got a friend request from a non-multi-device user. + */ + try { + PromiseUtil.timeout(LokiFileServerAPI.shared.addDeviceLink(deviceLink), 8000).get(); + } catch (Exception e) { + Log.w("Loki", "Failed to upload device links to the file server! " + e); + } // Update display name if needed if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) { TextSecurePreferences.setProfileName(context, content.senderDisplayName.get()); @@ -1218,7 +1231,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getContacts().isPresent()) { handleContactSyncMessage(content.getSyncMessage().get().getContacts().get()); } - // The device link is propagated to the file server in LandingActivity.onDeviceLinkAuthorized because we can handle the error there } private void setDisplayName(String hexEncodedPublicKey, String profileName) { diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index 6afb77f165..8cbf546901 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -42,6 +42,12 @@ fun checkIsRevokedSlaveDevice(context: Context) { } } +fun updateDeviceLinksOnServer(context: Context) { + val hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) + val deviceLinks = DatabaseFactory.getLokiAPIDatabase(context).getDeviceLinks(hexEncodedPublicKey) + LokiFileServerAPI.shared.setDeviceLinks(deviceLinks) +} + fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: String): Promise, Exception> { val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) return LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(hexEncodedPublicKey).map { keys -> diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt index f8031a22b7..130646d4fa 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt @@ -114,7 +114,6 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega } override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { - LokiFileServerAPI.shared.addDeviceLink(deviceLink) TextSecurePreferences.setMasterHexEncodedPublicKey(this, deviceLink.masterHexEncodedPublicKey) val intent = Intent(this, HomeActivity::class.java) show(intent) From a9ba2b51010d3af932180ae23c0072c1a0b525c8 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 26 Feb 2020 10:02:39 +0700 Subject: [PATCH 05/13] Update build number --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6a0b002293..f8c212d7fa 100644 --- a/build.gradle +++ b/build.gradle @@ -199,7 +199,7 @@ dependencies { implementation "com.github.ybq:Android-SpinKit:1.4.0" } -def canonicalVersionCode = 37 +def canonicalVersionCode = 38 def canonicalVersionName = "1.0.3" def postFixSize = 10 From 7c89f5ce1a86fb456113b09392563ccae2bfceb0 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 26 Feb 2020 10:09:19 +0700 Subject: [PATCH 06/13] Update version number --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f8c212d7fa..34a1999489 100644 --- a/build.gradle +++ b/build.gradle @@ -200,7 +200,7 @@ dependencies { } def canonicalVersionCode = 38 -def canonicalVersionName = "1.0.3" +def canonicalVersionName = "1.0.4" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1, From dd0b9c80b017d64156eaa4855c960f0431b59ba2 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Wed, 26 Feb 2020 16:56:07 +1100 Subject: [PATCH 07/13] Fix device linking blocking the main promise thread. --- .../activities/LinkedDevicesActivity.kt | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index 759362b91c..1def8899cd 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -12,6 +12,7 @@ import android.view.View import android.widget.Toast import kotlinx.android.synthetic.main.activity_linked_devices.* import network.loki.messenger.R +import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity @@ -23,6 +24,7 @@ import org.thoughtcrime.securesms.loki.signAndSendDeviceLinkMessage import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.loki.api.DeviceLink +import org.whispersystems.signalservice.loki.api.LokiAPI import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import java.util.* import kotlin.concurrent.schedule @@ -143,23 +145,20 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager } override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { - LokiFileServerAPI.shared.addDeviceLink(deviceLink).success { - signAndSendDeviceLinkMessage(this, deviceLink).successUi { - LoaderManager.getInstance(this).restartLoader(0, null, this) - }.success { - TextSecurePreferences.setMultiDevice(this, true) - Timer().schedule(4000) { - MessageSender.syncAllGroups(this@LinkedDevicesActivity) - MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey)) - } - }.failUi { - Toast.makeText(this, "Couldn't link device", Toast.LENGTH_LONG).show() - }.fail { - LokiFileServerAPI.shared.removeDeviceLink(deviceLink) // If this fails we have a problem - DatabaseFactory.getLokiPreKeyBundleDatabase(this).removePreKeyBundle(deviceLink.slaveHexEncodedPublicKey) + LokiFileServerAPI.shared.addDeviceLink(deviceLink).bind(LokiAPI.sharedWorkContext) { + signAndSendDeviceLinkMessage(this, deviceLink) + }.successUi { + LoaderManager.getInstance(this).restartLoader(0, null, this) + }.success { + TextSecurePreferences.setMultiDevice(this, true) + Timer().schedule(4000) { + MessageSender.syncAllGroups(this@LinkedDevicesActivity) + MessageSender.syncAllContacts(this@LinkedDevicesActivity, Address.fromSerialized(deviceLink.slaveHexEncodedPublicKey)) } - }.failUi { + }.fail { + LokiFileServerAPI.shared.removeDeviceLink(deviceLink) // If this fails we have a problem DatabaseFactory.getLokiPreKeyBundleDatabase(this).removePreKeyBundle(deviceLink.slaveHexEncodedPublicKey) + }.failUi { Toast.makeText(this, "Couldn't link device", Toast.LENGTH_LONG).show() } } From a57bf0cd98d7f357e9a68e7e1388469d85ccfc39 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Thu, 27 Feb 2020 15:36:22 +1100 Subject: [PATCH 08/13] Remove un-used permissions. --- AndroidManifest.xml | 69 ++------ res/layout/conversation_item_footer.xml | 21 +-- .../securesms/ApplicationContext.java | 13 -- .../securesms/RegistrationActivity.java | 9 +- .../components/ConversationItemFooter.java | 32 +--- .../contacts/ContactsSyncAdapter.java | 49 ------ .../SignalCommunicationModule.java | 4 - .../securesms/gcm/FcmService.java | 158 ------------------ .../thoughtcrime/securesms/gcm/FcmUtil.java | 44 ----- .../migration/WorkManagerFactoryMappings.java | 2 - .../securesms/jobs/FcmRefreshJob.java | 151 ----------------- .../securesms/jobs/JobManagerFactories.java | 1 - .../service/ContactsSyncAdapterService.java | 26 --- 13 files changed, 18 insertions(+), 561 deletions(-) delete mode 100644 src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java delete mode 100644 src/org/thoughtcrime/securesms/gcm/FcmService.java delete mode 100644 src/org/thoughtcrime/securesms/gcm/FcmUtil.java delete mode 100644 src/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java delete mode 100644 src/org/thoughtcrime/securesms/service/ContactsSyncAdapterService.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 0e5a5d0654..53fe7fd3e3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -38,58 +38,36 @@ - - - - - - - - - + + - + - - + - - + - - - + + - - + + + + + + + - - - - - - - - @@ -612,11 +576,6 @@ - - - - - - - - fcmToken; - - if (gcmSupported) { - fcmToken = FcmUtil.getToken(); - } else { - fcmToken = Optional.absent(); - } + Optional fcmToken = Optional.absent(); accountManager = AccountManagerFactory.createManager(RegistrationActivity.this, e164number, password); accountManager.requestSmsVerificationCode(smsRetrieverSupported, registrationState.captchaToken); diff --git a/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java b/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java index 00c50630d6..cf30ea76b9 100644 --- a/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java +++ b/src/org/thoughtcrime/securesms/components/ConversationItemFooter.java @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.components; -import android.Manifest; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; @@ -14,22 +13,18 @@ import android.widget.LinearLayout; import android.widget.TextView; import org.thoughtcrime.securesms.ApplicationContext; -import network.loki.messenger.R; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.model.MessageRecord; -import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.util.DateUtils; -import org.thoughtcrime.securesms.util.dualsim.SubscriptionInfoCompat; -import org.thoughtcrime.securesms.util.dualsim.SubscriptionManagerCompat; -import org.whispersystems.libsignal.util.guava.Optional; import java.util.Locale; +import network.loki.messenger.R; + public class ConversationItemFooter extends LinearLayout { private TextView dateView; - private TextView simView; private ExpirationTimerView timerView; private ImageView insecureIndicatorView; private DeliveryStatusView deliveryStatusView; @@ -53,7 +48,6 @@ public class ConversationItemFooter extends LinearLayout { inflate(getContext(), R.layout.conversation_item_footer, this); dateView = findViewById(R.id.footer_date); - simView = findViewById(R.id.footer_sim_info); timerView = findViewById(R.id.footer_expiration_timer); insecureIndicatorView = findViewById(R.id.footer_insecure_indicator); deliveryStatusView = findViewById(R.id.footer_delivery_status); @@ -74,7 +68,6 @@ public class ConversationItemFooter extends LinearLayout { public void setMessageRecord(@NonNull MessageRecord messageRecord, @NonNull Locale locale) { presentDate(messageRecord, locale); - presentSimInfo(messageRecord); presentTimer(messageRecord); presentInsecureIndicator(messageRecord); presentDeliveryStatus(messageRecord); @@ -82,7 +75,6 @@ public class ConversationItemFooter extends LinearLayout { public void setTextColor(int color) { dateView.setTextColor(color); - simView.setTextColor(color); } public void setIconColor(int color) { @@ -103,26 +95,6 @@ public class ConversationItemFooter extends LinearLayout { } } - private void presentSimInfo(@NonNull MessageRecord messageRecord) { - SubscriptionManagerCompat subscriptionManager = new SubscriptionManagerCompat(getContext()); - - if (messageRecord.isPush() || messageRecord.getSubscriptionId() == -1 || !Permissions.hasAll(getContext(), Manifest.permission.READ_PHONE_STATE) || !subscriptionManager.isMultiSim()) { - simView.setVisibility(View.GONE); - } else { - Optional subscriptionInfo = subscriptionManager.getActiveSubscriptionInfo(messageRecord.getSubscriptionId()); - - if (subscriptionInfo.isPresent() && messageRecord.isOutgoing()) { - simView.setText(getContext().getString(R.string.ConversationItem_from_s, subscriptionInfo.get().getDisplayName())); - simView.setVisibility(View.VISIBLE); - } else if (subscriptionInfo.isPresent()) { - simView.setText(getContext().getString(R.string.ConversationItem_to_s, subscriptionInfo.get().getDisplayName())); - simView.setVisibility(View.VISIBLE); - } else { - simView.setVisibility(View.GONE); - } - } - } - @SuppressLint("StaticFieldLeak") private void presentTimer(@NonNull final MessageRecord messageRecord) { if (messageRecord.getExpiresIn() > 0 && !messageRecord.isPending()) { diff --git a/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java b/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java deleted file mode 100644 index 71d3b790d1..0000000000 --- a/src/org/thoughtcrime/securesms/contacts/ContactsSyncAdapter.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.thoughtcrime.securesms.contacts; - -import android.accounts.Account; -import android.content.AbstractThreadedSyncAdapter; -import android.content.ContentProviderClient; -import android.content.Context; -import android.content.SyncResult; -import android.os.Bundle; -import org.thoughtcrime.securesms.logging.Log; - -import org.thoughtcrime.securesms.util.DirectoryHelper; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.io.IOException; - -public class ContactsSyncAdapter extends AbstractThreadedSyncAdapter { - - private static final String TAG = ContactsSyncAdapter.class.getSimpleName(); - - public ContactsSyncAdapter(Context context, boolean autoInitialize) { - super(context, autoInitialize); - } - - @Override - public void onPerformSync(Account account, Bundle extras, String authority, - ContentProviderClient provider, SyncResult syncResult) - { - Log.i(TAG, "onPerformSync(" + authority +")"); - - if (TextSecurePreferences.isPushRegistered(getContext())) { - try { - DirectoryHelper.refreshDirectory(getContext(), true); - } catch (IOException e) { - Log.w(TAG, e); - } - } - } - - @Override - public void onSyncCanceled() { - Log.w(TAG, "onSyncCanceled()"); - } - - @Override - public void onSyncCanceled(Thread thread) { - Log.w(TAG, "onSyncCanceled(" + thread + ")"); - } - -} diff --git a/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java b/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java index c59224d481..9e1bf481f1 100644 --- a/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java +++ b/src/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java @@ -9,13 +9,11 @@ import org.thoughtcrime.securesms.DeviceListFragment; import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.events.ReminderUpdateEvent; -import org.thoughtcrime.securesms.gcm.FcmService; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; import org.thoughtcrime.securesms.jobs.AttachmentUploadJob; import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; -import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; @@ -86,7 +84,6 @@ import network.loki.messenger.BuildConfig; MultiDeviceBlockedUpdateJob.class, DeviceListFragment.class, RefreshAttributesJob.class, - FcmRefreshJob.class, RequestGroupInfoJob.class, PushGroupUpdateJob.class, AvatarDownloadJob.class, @@ -99,7 +96,6 @@ import network.loki.messenger.BuildConfig; MultiDeviceProfileKeyUpdateJob.class, SendReadReceiptJob.class, AppProtectionPreferenceFragment.class, - FcmService.class, RotateCertificateJob.class, SendDeliveryReceiptJob.class, RotateProfileKeyJob.class, diff --git a/src/org/thoughtcrime/securesms/gcm/FcmService.java b/src/org/thoughtcrime/securesms/gcm/FcmService.java deleted file mode 100644 index cbb3da3807..0000000000 --- a/src/org/thoughtcrime/securesms/gcm/FcmService.java +++ /dev/null @@ -1,158 +0,0 @@ -package org.thoughtcrime.securesms.gcm; - -import android.content.Context; -import android.os.PowerManager; -import android.support.annotation.NonNull; - -import com.google.firebase.messaging.FirebaseMessagingService; -import com.google.firebase.messaging.RemoteMessage; - -import org.thoughtcrime.securesms.ApplicationContext; -import network.loki.messenger.R; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.jobs.FcmRefreshJob; -import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.service.GenericForegroundService; -import org.thoughtcrime.securesms.util.PowerManagerCompat; -import org.thoughtcrime.securesms.util.ServiceUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.thoughtcrime.securesms.util.WakeLockUtil; -import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; -import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; -import org.whispersystems.signalservice.internal.util.Util; - -import java.io.IOException; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.inject.Inject; - -public class FcmService extends FirebaseMessagingService implements InjectableType { - - private static final String TAG = FcmService.class.getSimpleName(); - - private static final Executor MESSAGE_EXECUTOR = SignalExecutors.newCachedSingleThreadExecutor("FcmMessageProcessing"); - private static final String WAKE_LOCK_TAG = "FcmMessageProcessing"; - - @Inject SignalServiceMessageReceiver messageReceiver; - - private static int activeCount; - - @Override - public void onMessageReceived(RemoteMessage remoteMessage) { - Log.i(TAG, "FCM message... Original Priority: " + remoteMessage.getOriginalPriority() + ", Actual Priority: " + remoteMessage.getPriority()); - ApplicationContext.getInstance(getApplicationContext()).injectDependencies(this); - - WakeLockUtil.runWithLock(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK, 60000, WAKE_LOCK_TAG, () -> { - handleReceivedNotification(getApplicationContext()); - }); - } - - @Override - public void onNewToken(String token) { - Log.i(TAG, "onNewToken()"); - - if (!TextSecurePreferences.isPushRegistered(getApplicationContext())) { - Log.i(TAG, "Got a new FCM token, but the user isn't registered."); - return; - } - - ApplicationContext.getInstance(getApplicationContext()) - .getJobManager() - .add(new FcmRefreshJob()); - } - - private void handleReceivedNotification(Context context) { - if (!incrementActiveGcmCount()) { - Log.i(TAG, "Skipping FCM processing -- there's already one enqueued."); - return; - } - - TextSecurePreferences.setNeedsMessagePull(context, true); - - long startTime = System.currentTimeMillis(); - PowerManager powerManager = ServiceUtil.getPowerManager(getApplicationContext()); - boolean doze = PowerManagerCompat.isDeviceIdleMode(powerManager); - boolean network = new NetworkConstraint.Factory(ApplicationContext.getInstance(context)).create().isMet(); - - final Object foregroundLock = new Object(); - final AtomicBoolean foregroundRunning = new AtomicBoolean(false); - final AtomicBoolean taskCompleted = new AtomicBoolean(false); - final CountDownLatch latch = new CountDownLatch(1); - - if (doze || !network) { - Log.i(TAG, "Starting a foreground task because we may be operating in a constrained environment. Doze: " + doze + " Network: " + network); - showForegroundNotification(context); - foregroundRunning.set(true); - latch.countDown(); - } - - MESSAGE_EXECUTOR.execute(() -> { - try { - new PushNotificationReceiveJob(context).pullAndProcessMessages(messageReceiver, TAG, startTime); - } catch (IOException e) { - Log.i(TAG, "Failed to retrieve the envelope. Scheduling on JobManager.", e); - ApplicationContext.getInstance(context) - .getJobManager() - .add(new PushNotificationReceiveJob(context)); - } finally { - synchronized (foregroundLock) { - if (foregroundRunning.getAndSet(false)) { - GenericForegroundService.stopForegroundTask(context); - } else { - latch.countDown(); - } - taskCompleted.set(true); - } - - decrementActiveGcmCount(); - Log.i(TAG, "Processing complete."); - } - }); - - if (!foregroundRunning.get()) { - new Thread("FcmForegroundServiceTimer") { - @Override - public void run() { - Util.sleep(7000); - synchronized (foregroundLock) { - if (!taskCompleted.get() && !foregroundRunning.getAndSet(true)) { - Log.i(TAG, "Starting a foreground task because the job is running long."); - showForegroundNotification(context); - latch.countDown(); - } - } - } - }.start(); - } - - try { - latch.await(); - } catch (InterruptedException e) { - Log.w(TAG, "Latch was interrupted.", e); - } - } - - private void showForegroundNotification(@NonNull Context context) { - GenericForegroundService.startForegroundTask(context, - context.getString(R.string.GcmBroadcastReceiver_retrieving_a_message), - NotificationChannels.OTHER, - R.drawable.ic_signal_downloading); - } - - private static synchronized boolean incrementActiveGcmCount() { - if (activeCount < 2) { - activeCount++; - return true; - } - return false; - } - - private static synchronized void decrementActiveGcmCount() { - activeCount--; - } -} diff --git a/src/org/thoughtcrime/securesms/gcm/FcmUtil.java b/src/org/thoughtcrime/securesms/gcm/FcmUtil.java deleted file mode 100644 index 2a2e2b04d5..0000000000 --- a/src/org/thoughtcrime/securesms/gcm/FcmUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -package org.thoughtcrime.securesms.gcm; - -import android.support.annotation.WorkerThread; -import android.text.TextUtils; - -import com.google.firebase.iid.FirebaseInstanceId; - -import org.thoughtcrime.securesms.logging.Log; -import org.whispersystems.libsignal.util.guava.Optional; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicReference; - -public final class FcmUtil { - - private static final String TAG = FcmUtil.class.getSimpleName(); - - /** - * Retrieves the current FCM token. If one isn't available, it'll be generated. - */ - @WorkerThread - public static Optional getToken() { - CountDownLatch latch = new CountDownLatch(1); - AtomicReference token = new AtomicReference<>(null); - - FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(task -> { - if (task.isSuccessful() && task.getResult() != null && !TextUtils.isEmpty(task.getResult().getToken())) { - token.set(task.getResult().getToken()); - } else { - Log.w(TAG, "Failed to get the token.", task.getException()); - } - - latch.countDown(); - }); - - try { - latch.await(); - } catch (InterruptedException e) { - Log.w(TAG, "Was interrupted while waiting for the token."); - } - - return Optional.fromNullable(token.get()); - } -} diff --git a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java index 156fdf9b0f..4957ebd72d 100644 --- a/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java +++ b/src/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java @@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.DirectoryRefreshJob; -import org.thoughtcrime.securesms.jobs.FcmRefreshJob; import org.thoughtcrime.securesms.jobs.LocalBackupJob; import org.thoughtcrime.securesms.jobs.MmsDownloadJob; import org.thoughtcrime.securesms.jobs.MmsReceiveJob; @@ -59,7 +58,6 @@ public class WorkManagerFactoryMappings { put(CleanPreKeysJob.class.getName(), CleanPreKeysJob.KEY); put(CreateSignedPreKeyJob.class.getName(), CreateSignedPreKeyJob.KEY); put(DirectoryRefreshJob.class.getName(), DirectoryRefreshJob.KEY); - put(FcmRefreshJob.class.getName(), FcmRefreshJob.KEY); put(LocalBackupJob.class.getName(), LocalBackupJob.KEY); put(MmsDownloadJob.class.getName(), MmsDownloadJob.KEY); put(MmsReceiveJob.class.getName(), MmsReceiveJob.KEY); diff --git a/src/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java b/src/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java deleted file mode 100644 index 2f63316d2a..0000000000 --- a/src/org/thoughtcrime/securesms/jobs/FcmRefreshJob.java +++ /dev/null @@ -1,151 +0,0 @@ -/** - * Copyright (C) 2014 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.jobs; - -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.BitmapFactory; -import android.support.annotation.NonNull; -import android.support.v4.app.NotificationCompat; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - -import org.thoughtcrime.securesms.gcm.FcmUtil; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; - -import org.thoughtcrime.securesms.PlayServicesProblemActivity; -import network.loki.messenger.R; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.notifications.NotificationChannels; -import org.thoughtcrime.securesms.transport.RetryLaterException; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.whispersystems.libsignal.util.guava.Optional; -import org.whispersystems.signalservice.api.SignalServiceAccountManager; -import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class FcmRefreshJob extends BaseJob implements InjectableType { - - public static final String KEY = "FcmRefreshJob"; - - private static final String TAG = FcmRefreshJob.class.getSimpleName(); - - @Inject SignalServiceAccountManager textSecureAccountManager; - - public FcmRefreshJob() { - this(new Job.Parameters.Builder() - .setQueue("FcmRefreshJob") - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(1) - .setLifespan(TimeUnit.MINUTES.toMillis(5)) - .setMaxInstances(1) - .build()); - } - - private FcmRefreshJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws Exception { - if (TextSecurePreferences.isFcmDisabled(context)) return; - - Log.i(TAG, "Reregistering FCM..."); - - int result = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context); - - if (result != ConnectionResult.SUCCESS) { - notifyFcmFailure(); - } else { - Optional token = FcmUtil.getToken(); - - if (token.isPresent()) { - String oldToken = TextSecurePreferences.getFcmToken(context); - - if (!token.get().equals(oldToken)) { - int oldLength = oldToken != null ? oldToken.length() : -1; - Log.i(TAG, "Token changed. oldLength: " + oldLength + " newLength: " + token.get().length()); - } else { - Log.i(TAG, "Token didn't change."); - } - - textSecureAccountManager.setGcmId(token); - TextSecurePreferences.setFcmToken(context, token.get()); - TextSecurePreferences.setFcmTokenLastSetTime(context, System.currentTimeMillis()); - TextSecurePreferences.setWebsocketRegistered(context, true); - } else { - throw new RetryLaterException(new IOException("Failed to retrieve a token.")); - } - } - } - - @Override - public void onCanceled() { - Log.w(TAG, "GCM reregistration failed after retry attempt exhaustion!"); - } - - @Override - public boolean onShouldRetry(@NonNull Exception throwable) { - if (throwable instanceof NonSuccessfulResponseCodeException) return false; - return true; - } - - private void notifyFcmFailure() { - Intent intent = new Intent(context, PlayServicesProblemActivity.class); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 1122, intent, PendingIntent.FLAG_CANCEL_CURRENT); - NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NotificationChannels.FAILURES); - - builder.setSmallIcon(R.drawable.ic_notification); - builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), - R.drawable.ic_action_warning_red)); - builder.setContentTitle(context.getString(R.string.GcmRefreshJob_Permanent_Signal_communication_failure)); - builder.setContentText(context.getString(R.string.GcmRefreshJob_Signal_was_unable_to_register_with_Google_Play_Services)); - builder.setTicker(context.getString(R.string.GcmRefreshJob_Permanent_Signal_communication_failure)); - builder.setVibrate(new long[] {0, 1000}); - builder.setContentIntent(pendingIntent); - - ((NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE)) - .notify(12, builder.build()); - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull FcmRefreshJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new FcmRefreshJob(parameters); - } - } -} diff --git a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index cfa9aa7beb..266d6194df 100644 --- a/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/src/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -31,7 +31,6 @@ public final class JobManagerFactories { put(CleanPreKeysJob.KEY, new CleanPreKeysJob.Factory()); put(CreateSignedPreKeyJob.KEY, new CreateSignedPreKeyJob.Factory()); put(DirectoryRefreshJob.KEY, new DirectoryRefreshJob.Factory(application)); - put(FcmRefreshJob.KEY, new FcmRefreshJob.Factory()); put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory()); put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory()); diff --git a/src/org/thoughtcrime/securesms/service/ContactsSyncAdapterService.java b/src/org/thoughtcrime/securesms/service/ContactsSyncAdapterService.java deleted file mode 100644 index c162d9104d..0000000000 --- a/src/org/thoughtcrime/securesms/service/ContactsSyncAdapterService.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.thoughtcrime.securesms.service; - -import android.app.Service; -import android.content.Intent; -import android.os.IBinder; -import android.support.annotation.Nullable; - -import org.thoughtcrime.securesms.contacts.ContactsSyncAdapter; - -public class ContactsSyncAdapterService extends Service { - - private static ContactsSyncAdapter syncAdapter; - - @Override - public synchronized void onCreate() { - if (syncAdapter == null) { - syncAdapter = new ContactsSyncAdapter(this, true); - } - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return syncAdapter.getSyncAdapterBinder(); - } -} From 3cdaf80c5d7dea237d92159d4e160b82c41b10a0 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Fri, 28 Feb 2020 09:07:01 +1100 Subject: [PATCH 09/13] Removed all references to google play and firebase. Removed phone number utils. Slowly remove signal code. --- AndroidManifest.xml | 21 +-- build.gradle | 23 +-- proguard-firebase-messaging.pro | 1 - proguard-google-play-services.pro | 19 --- res/layout/signal_map_view.xml | 2 + res/values/firebase_messaging.xml | 10 -- .../securesms/ApplicationContext.java | 23 --- .../PlayServicesProblemActivity.java | 30 ---- .../PlayServicesProblemFragment.java | 67 -------- .../securesms/RegistrationActivity.java | 152 +----------------- .../components/location/SignalMapView.java | 44 +---- .../components/location/SignalPlace.java | 18 ++- .../securesms/contactshare/ContactUtil.java | 14 +- .../conversation/ConversationActivity.java | 9 +- .../securesms/database/Address.java | 73 +-------- .../database/helpers/ClassicOpenHelper.java | 70 +------- .../database/loaders/CountryListLoader.java | 27 +--- .../securesms/mms/AttachmentManager.java | 14 +- .../AdvancedPreferenceFragment.java | 13 +- .../securesms/push/AccountManagerFactory.java | 21 +-- .../StickerPackPreviewRepository.java | 6 +- .../stickers/StickerRemoteUriFetcher.java | 6 +- .../securesms/util/PlayServicesUtil.java | 61 ------- .../securesms/util/ShortCodeUtil.java | 25 +-- src/org/thoughtcrime/securesms/util/Util.java | 49 +----- 25 files changed, 69 insertions(+), 729 deletions(-) delete mode 100644 proguard-firebase-messaging.pro delete mode 100644 proguard-google-play-services.pro delete mode 100644 res/values/firebase_messaging.xml delete mode 100644 src/org/thoughtcrime/securesms/PlayServicesProblemActivity.java delete mode 100644 src/org/thoughtcrime/securesms/PlayServicesProblemFragment.java delete mode 100644 src/org/thoughtcrime/securesms/util/PlayServicesUtil.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 53fe7fd3e3..6a3cd05962 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -79,22 +79,13 @@ android:theme="@style/Session.DarkTheme" tools:replace="android:allowBackup"> - - - - + + @@ -440,10 +431,6 @@ android:noHistory="true" android:stateNotNeeded="true" android:theme="@android:style/Theme.NoDisplay" /> - diff --git a/build.gradle b/build.gradle index 34a1999489..853e76e084 100644 --- a/build.gradle +++ b/build.gradle @@ -11,13 +11,11 @@ buildscript { mavenLocal() google() mavenCentral() - maven { url 'https://maven.fabric.io/public' } } dependencies { classpath "com.android.tools.build:gradle:$gradle_version" classpath files('libs/gradle-witness.jar') classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath "io.fabric.tools:gradle:1.+" } } @@ -25,7 +23,6 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android' apply plugin: 'witness' -apply plugin: 'io.fabric' apply plugin: 'kotlin-kapt' repositories { @@ -62,7 +59,6 @@ repositories { } google() jcenter() - maven { url 'https://maven.fabric.io/public' } maven { url "https://jitpack.io" } } @@ -91,16 +87,6 @@ dependencies { implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'android.arch.lifecycle:common-java8:1.1.1' - implementation('com.google.firebase:firebase-messaging:17.3.4') { - exclude group: 'com.google.firebase', module: 'firebase-core' - exclude group: 'com.google.firebase', module: 'firebase-analytics' - exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' - } - - implementation 'com.google.android.gms:play-services-maps:16.0.0' - implementation 'com.google.android.gms:play-services-places:16.0.0' - implementation 'com.google.android.gms:play-services-auth:16.0.1' - implementation 'com.google.android.exoplayer:exoplayer-core:2.9.1' implementation 'com.google.android.exoplayer:exoplayer-ui:2.9.1' @@ -186,7 +172,6 @@ dependencies { // Remote: // implementation "com.github.loki-project:loki-messenger-android-service:dev-SNAPSHOT" implementation "com.google.protobuf:protobuf-java:2.5.0" - implementation "com.googlecode.libphonenumber:libphonenumber:8.10.7" implementation "com.fasterxml.jackson.core:jackson-databind:2.9.8" implementation "com.squareup.okhttp3:okhttp:3.12.1" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" @@ -279,8 +264,6 @@ android { debug { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), - 'proguard-firebase-messaging.pro', - 'proguard-google-play-services.pro', 'proguard-dagger.pro', 'proguard-jackson.pro', 'proguard-sqlite.pro', @@ -371,12 +354,12 @@ android { def assembleWebsiteDescriptor = { variant, file -> if (file.exists()) { - MessageDigest md = MessageDigest.getInstance("SHA-256"); + MessageDigest md = MessageDigest.getInstance("SHA-256") file.eachByte 4096, {bytes, size -> - md.update(bytes, 0, size); + md.update(bytes, 0, size) } - String digest = md.digest().collect {String.format "%02x", it}.join(); + String digest = md.digest().collect {String.format "%02x", it}.join() String url = variant.productFlavors.get(0).ext.websiteUpdateUrl String apkName = file.getName() diff --git a/proguard-firebase-messaging.pro b/proguard-firebase-messaging.pro deleted file mode 100644 index 17af8ca94c..0000000000 --- a/proguard-firebase-messaging.pro +++ /dev/null @@ -1 +0,0 @@ --dontwarn com.google.firebase.analytics.connector.AnalyticsConnector \ No newline at end of file diff --git a/proguard-google-play-services.pro b/proguard-google-play-services.pro deleted file mode 100644 index ae70fc4e49..0000000000 --- a/proguard-google-play-services.pro +++ /dev/null @@ -1,19 +0,0 @@ -## Google Play Services 4.3.23 specific rules ## -## https://developer.android.com/google/play-services/setup.html#Proguard ## - --keep class * extends java.util.ListResourceBundle { - protected Object[][] getContents(); -} - --keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { - public static final *** NULL; -} - --keepnames @com.google.android.gms.common.annotation.KeepName class * --keepclassmembernames class * { - @com.google.android.gms.common.annotation.KeepName *; -} - --keepnames class * implements android.os.Parcelable { - public static final ** CREATOR; -} \ No newline at end of file diff --git a/res/layout/signal_map_view.xml b/res/layout/signal_map_view.xml index dd87d28f8e..5a774b5457 100644 --- a/res/layout/signal_map_view.xml +++ b/res/layout/signal_map_view.xml @@ -5,11 +5,13 @@ + - - 1:312334754206:android:a9297b152879f266 - 312334754206 - 312334754206-dg1p1mtekis8ivja3ica50vonmrlunh4.apps.googleusercontent.com - https://api-project-312334754206.firebaseio.com - AIzaSyDrfzNAPBPzX6key51hqo3p5LZXF5Y-yxU - AIzaSyDrfzNAPBPzX6key51hqo3p5LZXF5Y-yxU - api-project-312334754206 - \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 81d847d32f..ccef1114d2 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -16,7 +16,6 @@ */ package org.thoughtcrime.securesms; -import android.annotation.SuppressLint; import android.arch.lifecycle.DefaultLifecycleObserver; import android.arch.lifecycle.LifecycleOwner; import android.arch.lifecycle.ProcessLifecycleOwner; @@ -31,8 +30,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.multidex.MultiDexApplication; -import com.google.android.gms.security.ProviderInstaller; - import org.conscrypt.Conscrypt; import org.jetbrains.annotations.NotNull; import org.signal.aesgcmprovider.AesGcmProvider; @@ -176,7 +173,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc initializeTypingStatusSender(); initializeSignedPreKeyCheck(); initializePeriodicTasks(); - initializeCircumvention(); initializeWebRtc(); initializePendingMessages(); initializeUnidentifiedDeliveryAbilityRefresh(); @@ -403,25 +399,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } } - @SuppressLint("StaticFieldLeak") - private void initializeCircumvention() { - AsyncTask task = new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - if (new SignalServiceNetworkAccess(ApplicationContext.this).isCensored(ApplicationContext.this)) { - try { - ProviderInstaller.installIfNeeded(ApplicationContext.this); - } catch (Throwable t) { - Log.w(TAG, t); - } - } - return null; - } - }; - - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - private void executePendingContactSync() { if (TextSecurePreferences.needsFullContactSync(this)) { ApplicationContext.getInstance(this).getJobManager().add(new MultiDeviceContactUpdateJob(this, true)); diff --git a/src/org/thoughtcrime/securesms/PlayServicesProblemActivity.java b/src/org/thoughtcrime/securesms/PlayServicesProblemActivity.java deleted file mode 100644 index 216fab99f3..0000000000 --- a/src/org/thoughtcrime/securesms/PlayServicesProblemActivity.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright (C) 2014 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; - -import android.os.Bundle; -import android.support.v4.app.FragmentActivity; - -public class PlayServicesProblemActivity extends FragmentActivity { - - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - PlayServicesProblemFragment fragment = new PlayServicesProblemFragment(); - fragment.show(getSupportFragmentManager(), "dialog"); - } -} diff --git a/src/org/thoughtcrime/securesms/PlayServicesProblemFragment.java b/src/org/thoughtcrime/securesms/PlayServicesProblemFragment.java deleted file mode 100644 index 6931e8430b..0000000000 --- a/src/org/thoughtcrime/securesms/PlayServicesProblemFragment.java +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Copyright (C) 2014 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; - -import android.app.Activity; -import android.app.Dialog; -import android.content.DialogInterface; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v4.app.DialogFragment; -import android.support.v7.app.AlertDialog; - -import com.google.android.gms.common.GoogleApiAvailability; - -import network.loki.messenger.R; - -public class PlayServicesProblemFragment extends DialogFragment { - - @Override - public @NonNull Dialog onCreateDialog(@Nullable Bundle bundle) { - int code = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(getActivity()); - Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(getActivity(), code, 9111); - - if (dialog == null) { - return new AlertDialog.Builder(requireActivity()) - .setNegativeButton(android.R.string.ok, null) - .setMessage(R.string.PlayServicesProblemFragment_the_version_of_google_play_services_you_have_installed_is_not_functioning) - .create(); - } else { - return dialog; - } - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - finish(); - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - finish(); - } - - private void finish() { - Activity activity = getActivity(); - if (activity != null) activity.finish(); - } - -} diff --git a/src/org/thoughtcrime/securesms/RegistrationActivity.java b/src/org/thoughtcrime/securesms/RegistrationActivity.java index ed16f160d7..ff09e7ed93 100644 --- a/src/org/thoughtcrime/securesms/RegistrationActivity.java +++ b/src/org/thoughtcrime/securesms/RegistrationActivity.java @@ -3,10 +3,8 @@ package org.thoughtcrime.securesms; import android.Manifest; import android.animation.Animator; import android.annotation.SuppressLint; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.NonNull; @@ -29,17 +27,6 @@ import android.widget.TextView; import android.widget.Toast; import com.dd.CircularProgressButton; -import com.google.android.gms.auth.api.phone.SmsRetriever; -import com.google.android.gms.auth.api.phone.SmsRetrieverClient; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; -import com.google.android.gms.common.api.CommonStatusCodes; -import com.google.android.gms.common.api.Status; -import com.google.android.gms.tasks.Task; -import com.google.i18n.phonenumbers.AsYouTypeFormatter; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; import net.sqlcipher.database.SQLiteDatabase; @@ -72,12 +59,9 @@ import org.thoughtcrime.securesms.push.AccountManagerFactory; import org.thoughtcrime.securesms.registration.CaptchaActivity; import org.thoughtcrime.securesms.service.DirectoryRefreshListener; import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener; -import org.thoughtcrime.securesms.service.VerificationCodeParser; import org.thoughtcrime.securesms.util.BackupUtil; import org.thoughtcrime.securesms.util.DateUtils; import org.thoughtcrime.securesms.util.Dialogs; -import org.thoughtcrime.securesms.util.PlayServicesUtil; -import org.thoughtcrime.securesms.util.PlayServicesUtil.PlayServicesStatus; import org.thoughtcrime.securesms.util.ServiceUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; @@ -120,7 +104,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif private static final String TAG = RegistrationActivity.class.getSimpleName(); - private AsYouTypeFormatter countryFormatter; private ArrayAdapter countrySpinnerAdapter; private Spinner countrySpinner; private LabeledEditText countryCode; @@ -148,7 +131,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif private VerificationPinKeyboard keyboard; private VerificationCodeView verificationCodeView; private RegistrationState registrationState; - private SmsRetrieverReceiver smsRetrieverReceiver; private SignalServiceAccountManager accountManager; private int debugTapCounter; @@ -162,13 +144,11 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif initializeSpinner(); initializeNumber(); initializeBackupDetection(); - initializeChallengeListener(); } @Override public void onDestroy() { super.onDestroy(); - shutdownChallengeListener(); markAsVerifying(false); EventBus.getDefault().unregister(this); } @@ -178,7 +158,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif if (requestCode == PICK_COUNTRY && resultCode == RESULT_OK && data != null) { this.countryCode.setText(String.valueOf(data.getIntExtra("country_code", 1))); setCountryDisplay(data.getStringExtra("country_name")); - setCountryFormatter(data.getIntExtra("country_code", 1)); } else if (requestCode == CAPTCHA && resultCode == RESULT_OK && data != null) { registrationState = new RegistrationState(Optional.fromNullable(data.getStringExtra(CaptchaActivity.KEY_TOKEN)), registrationState); @@ -285,24 +264,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif }); } - @SuppressLint("MissingPermission") private void initializeNumber() { - Optional localNumber = Optional.absent(); - - if (Permissions.hasAll(this, Manifest.permission.READ_PHONE_STATE)) { - localNumber = Util.getDeviceNumber(this); - } - - if (localNumber.isPresent()) { - this.countryCode.setText(String.valueOf(localNumber.get().getCountryCode())); - this.number.setText(String.valueOf(localNumber.get().getNationalNumber())); - } else { - Optional simCountryIso = Util.getSimCountryIso(this); - - if (simCountryIso.isPresent() && !TextUtils.isEmpty(simCountryIso.get())) { - this.countryCode.setText(String.valueOf(PhoneNumberUtil.getInstance().getCountryCodeForRegion(simCountryIso.get()))); - } - } } @SuppressLint("StaticFieldLeak") @@ -337,14 +299,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif this.countrySpinnerAdapter.add(value); } - private void setCountryFormatter(int countryCode) { - PhoneNumberUtil util = PhoneNumberUtil.getInstance(); - String regionCode = util.getRegionCodeForCountryCode(countryCode); - - if (regionCode == null) this.countryFormatter = null; - else this.countryFormatter = util.getAsYouTypeFormatter(regionCode); - } - private String getConfiguredE164Number() { return PhoneNumberFormatter.formatE164(countryCode.getText().toString(), number.getText().toString()); @@ -435,20 +389,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif Dialogs.showAlertDialog(this, getString(R.string.RegistrationActivity_invalid_number), String.format(getString(R.string.RegistrationActivity_the_number_you_specified_s_is_invalid), e164number)); - return; - } - - PlayServicesStatus gcmStatus = PlayServicesUtil.getPlayServicesStatus(this); - - if (gcmStatus == PlayServicesStatus.SUCCESS) { - handleRequestVerification(e164number, true); - } else if (gcmStatus == PlayServicesStatus.MISSING) { - handlePromptForNoPlayServices(e164number); - } else if (gcmStatus == PlayServicesStatus.NEEDS_UPDATE) { - GoogleApiAvailability.getInstance().getErrorDialog(this, ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED, 0).show(); - } else { - Dialogs.showAlertDialog(this, getString(R.string.RegistrationActivity_play_services_error), - getString(R.string.RegistrationActivity_google_play_services_is_updating_or_unavailable)); } } @@ -456,22 +396,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif createButton.setIndeterminateProgressMode(true); createButton.setProgress(50); - if (gcmSupported) { - SmsRetrieverClient client = SmsRetriever.getClient(this); - Task task = client.startSmsRetriever(); - - task.addOnSuccessListener(none -> { - Log.i(TAG, "Successfully registered SMS listener."); - requestVerificationCode(e164number, true, true); - }); - - task.addOnFailureListener(e -> { - Log.w(TAG, "Failed to register SMS listener.", e); - requestVerificationCode(e164number, true, false); - }); - } else { requestVerificationCode(e164number, false, false); - } } @SuppressLint("StaticFieldLeak") @@ -932,19 +857,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif dialog.show(); } - private void initializeChallengeListener() { - smsRetrieverReceiver = new SmsRetrieverReceiver(); - IntentFilter filter = new IntentFilter(SmsRetriever.SMS_RETRIEVED_ACTION); - registerReceiver(smsRetrieverReceiver, filter); - } - - private void shutdownChallengeListener() { - if (smsRetrieverReceiver != null) { - unregisterReceiver(smsRetrieverReceiver); - smsRetrieverReceiver = null; - } - } - private void markAsVerifying(boolean verifying) { TextSecurePreferences.setVerifying(this, verifying); @@ -954,12 +866,7 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif } private String formatNumber(@NonNull String e164Number) { - try { - Phonenumber.PhoneNumber number = PhoneNumberUtil.getInstance().parse(e164Number, null); - return PhoneNumberUtil.getInstance().format(number, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL); - } catch (NumberParseException e) { - return e164Number; - } + return e164Number; } private void onWrongNumberClicked() { @@ -973,53 +880,16 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif else restoreBackupProgress.setText(getString(R.string.RegistrationActivity_d_messages_so_far, event.getCount())); } - private class SmsRetrieverReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "SmsRetrieverReceiver received a broadcast..."); - - if (SmsRetriever.SMS_RETRIEVED_ACTION.equals(intent.getAction())) { - Bundle extras = intent.getExtras(); - Status status = (Status) extras.get(SmsRetriever.EXTRA_STATUS); - - switch (status.getStatusCode()) { - case CommonStatusCodes.SUCCESS: - Optional code = VerificationCodeParser.parse(context, (String) extras.get(SmsRetriever.EXTRA_SMS_MESSAGE)); - if (code.isPresent()) { - Log.i(TAG, "Received verification code."); - handleVerificationCodeReceived(code.get()); - } else { - Log.w(TAG, "Could not parse verification code."); - } - break; - case CommonStatusCodes.TIMEOUT: - Log.w(TAG, "Hit a timeout waiting for the SMS to arrive."); - break; - } - } else { - Log.w(TAG, "SmsRetrieverReceiver received the wrong action?"); - } - } - } - private class CountryCodeChangedListener implements TextWatcher { @Override public void afterTextChanged(Editable s) { if (TextUtils.isEmpty(s) || !TextUtils.isDigitsOnly(s)) { setCountryDisplay(getString(R.string.RegistrationActivity_select_your_country)); - countryFormatter = null; return; } int countryCode = Integer.parseInt(s.toString()); - String regionCode = PhoneNumberUtil.getInstance().getRegionCodeForCountryCode(countryCode); - - setCountryFormatter(countryCode); - setCountryDisplay(PhoneNumberFormatter.getRegionDisplayName(regionCode)); - - if (!TextUtils.isEmpty(regionCode) && !regionCode.equals("ZZ")) { - number.requestFocus(); - } + setCountryDisplay("N/A"); } @Override @@ -1035,24 +905,6 @@ public class RegistrationActivity extends BaseActionBarActivity implements Verif @Override public void afterTextChanged(Editable s) { - if (countryFormatter == null) - return; - - if (TextUtils.isEmpty(s)) - return; - - countryFormatter.clear(); - - String number = s.toString().replaceAll("[^\\d.]", ""); - String formattedNumber = null; - - for (int i=0;i display(final SignalPlace place) { final SettableFuture future = new SettableFuture<>(); - this.mapView.onCreate(null); - this.mapView.onResume(); - - this.mapView.setVisibility(View.VISIBLE); this.imageView.setVisibility(View.GONE); - this.mapView.getMapAsync(new OnMapReadyCallback() { - @Override - public void onMapReady(final GoogleMap googleMap) { - googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(place.getLatLong(), 13)); - googleMap.addMarker(new MarkerOptions().position(place.getLatLong())); - googleMap.setBuildingsEnabled(true); - googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL); - googleMap.getUiSettings().setAllGesturesEnabled(false); - googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { - @Override - public void onMapLoaded() { - googleMap.snapshot(new GoogleMap.SnapshotReadyCallback() { - @Override - public void onSnapshotReady(Bitmap bitmap) { - future.set(bitmap); - imageView.setImageBitmap(bitmap); - imageView.setVisibility(View.VISIBLE); - mapView.setVisibility(View.GONE); - mapView.onPause(); - mapView.onDestroy(); - } - }); - } - }); - } - }); - this.textView.setText(place.getDescription()); return future; diff --git a/src/org/thoughtcrime/securesms/components/location/SignalPlace.java b/src/org/thoughtcrime/securesms/components/location/SignalPlace.java index b5a2219ee0..0519e8d2c2 100644 --- a/src/org/thoughtcrime/securesms/components/location/SignalPlace.java +++ b/src/org/thoughtcrime/securesms/components/location/SignalPlace.java @@ -7,8 +7,6 @@ import android.text.TextUtils; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.android.gms.location.places.Place; -import com.google.android.gms.maps.model.LatLng; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.util.JsonUtils; @@ -17,6 +15,22 @@ import java.io.IOException; public class SignalPlace { + /* Loki - Temporary Placeholders */ + class LatLng { + double latitude; + double longitude; + LatLng(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + } + + class Place { + public CharSequence getName() { return ""; } + public CharSequence getAddress() { return ""; } + LatLng getLatLng() { return new LatLng(0, 0); } + } + private static final String URL = "https://maps.google.com/maps"; private static final String TAG = SignalPlace.class.getSimpleName(); diff --git a/src/org/thoughtcrime/securesms/contactshare/ContactUtil.java b/src/org/thoughtcrime/securesms/contactshare/ContactUtil.java index cb4985892a..fbb7ddd641 100644 --- a/src/org/thoughtcrime/securesms/contactshare/ContactUtil.java +++ b/src/org/thoughtcrime/securesms/contactshare/ContactUtil.java @@ -13,11 +13,7 @@ import android.support.v7.app.AlertDialog; import android.text.TextUtils; import com.annimon.stream.Stream; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; -import network.loki.messenger.R; import org.thoughtcrime.securesms.components.emoji.EmojiStrings; import org.thoughtcrime.securesms.contactshare.Contact.Email; import org.thoughtcrime.securesms.contactshare.Contact.Phone; @@ -34,6 +30,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import network.loki.messenger.R; + public final class ContactUtil { private static final String TAG = ContactUtil.class.getSimpleName(); @@ -102,13 +100,7 @@ public final class ContactUtil { } private static @NonNull String getPrettyPhoneNumber(@NonNull String phoneNumber, @NonNull Locale fallbackLocale) { - PhoneNumberUtil util = PhoneNumberUtil.getInstance(); - try { - PhoneNumber parsed = util.parse(phoneNumber, fallbackLocale.getISO3Country()); - return util.format(parsed, PhoneNumberUtil.PhoneNumberFormat.INTERNATIONAL); - } catch (NumberParseException e) { - return phoneNumber; - } + return phoneNumber; } public static @NonNull String getNormalizedPhoneNumber(@NonNull Context context, @NonNull String number) { diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 35d2193a27..628e8c85ba 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -77,7 +77,6 @@ import android.widget.TextView; import android.widget.Toast; import com.annimon.stream.Stream; -import com.google.android.gms.location.places.ui.PlacePicker; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -133,7 +132,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DraftDatabase; import org.thoughtcrime.securesms.database.DraftDatabase.Draft; import org.thoughtcrime.securesms.database.DraftDatabase.Drafts; -import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase.IdentityRecord; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; @@ -179,7 +177,6 @@ import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.LocationSlide; import org.thoughtcrime.securesms.mms.MediaConstraints; import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; -import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; import org.thoughtcrime.securesms.mms.QuoteId; @@ -662,10 +659,12 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity recipient.addListener(this); fragment.reloadList(); break; + /* case PICK_LOCATION: SignalPlace place = new SignalPlace(PlacePicker.getPlace(data, this)); attachmentManager.setLocation(place, getCurrentMediaConstraints()); break; + */ case PICK_GIF: setMedia(data.getData(), MediaType.GIF, @@ -1240,15 +1239,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } private boolean handleDisplayQuickContact() { - if (recipient.getAddress().isGroup()) return false; + return !recipient.getAddress().isGroup(); // if (recipient.getContactUri() != null) { // ContactsContract.QuickContact.showQuickContact(ConversationActivity.this, titleView, recipient.getContactUri(), ContactsContract.QuickContact.MODE_LARGE, null); // } else { // handleAddToContacts(); // } - - return true; } private void handleAddAttachment() { diff --git a/src/org/thoughtcrime/securesms/database/Address.java b/src/org/thoughtcrime/securesms/database/Address.java index 1286b4b302..0969e0e14d 100644 --- a/src/org/thoughtcrime/securesms/database/Address.java +++ b/src/org/thoughtcrime/securesms/database/Address.java @@ -10,12 +10,6 @@ import android.support.annotation.VisibleForTesting; import android.text.TextUtils; import android.util.Pair; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; -import com.google.i18n.phonenumbers.ShortNumberInfo; - -import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.util.DelimiterUtil; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.NumberUtil; @@ -200,19 +194,10 @@ public class Address implements Parcelable, Comparable
{ private final Optional localNumber; private final String localCountryCode; - private final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); private final Pattern ALPHA_PATTERN = Pattern.compile("[a-zA-Z]"); ExternalAddressFormatter(@NonNull String localNumberString) { - try { - Phonenumber.PhoneNumber libNumber = phoneNumberUtil.parse(localNumberString, null); - int countryCode = libNumber.getCountryCode(); - - this.localNumber = Optional.of(new PhoneNumber(localNumberString, countryCode, parseAreaCode(localNumberString, countryCode))); - this.localCountryCode = phoneNumberUtil.getRegionCodeForNumber(libNumber); - } catch (NumberParseException e) { - throw new AssertionError(e); - } + throw new AssertionError("Not Implemented"); } ExternalAddressFormatter(@NonNull String localCountryCode, boolean countryCode) { @@ -222,61 +207,7 @@ public class Address implements Parcelable, Comparable
{ public String format(@Nullable String number) { if (number == null) return "Unknown"; - if (GroupUtil.isEncodedGroup(number)) return number; - if (ALPHA_PATTERN.matcher(number).find()) return number.trim(); - - String bareNumber = number.replaceAll("[^0-9+]", ""); - - if (bareNumber.length() == 0) { - if (number.trim().length() == 0) return "Unknown"; - else return number.trim(); - } - - // libphonenumber doesn't seem to be correct for Germany and Finland - if (bareNumber.length() <= 6 && ("DE".equals(localCountryCode) || "FI".equals(localCountryCode) || "SK".equals(localCountryCode))) { - return bareNumber; - } - - // libphonenumber seems incorrect for Russia and a few other countries with 4 digit short codes. - if (bareNumber.length() <= 4 && !SHORT_COUNTRIES.contains(localCountryCode)) { - return bareNumber; - } - - if (isShortCode(bareNumber, localCountryCode)) { - return bareNumber; - } - - String processedNumber = applyAreaCodeRules(localNumber, bareNumber); - - try { - Phonenumber.PhoneNumber parsedNumber = phoneNumberUtil.parse(processedNumber, localCountryCode); - return phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.E164); - } catch (NumberParseException e) { - Log.w(TAG, e); - if (bareNumber.charAt(0) == '+') - return bareNumber; - - String localNumberImprecise = localNumber.isPresent() ? localNumber.get().getE164Number() : ""; - - if (localNumberImprecise.charAt(0) == '+') - localNumberImprecise = localNumberImprecise.substring(1); - - if (localNumberImprecise.length() == bareNumber.length() || bareNumber.length() > localNumberImprecise.length()) - return "+" + number; - - int difference = localNumberImprecise.length() - bareNumber.length(); - - return "+" + localNumberImprecise.substring(0, difference) + bareNumber; - } - } - - private boolean isShortCode(@NonNull String bareNumber, String localCountryCode) { - try { - Phonenumber.PhoneNumber parsedNumber = phoneNumberUtil.parse(bareNumber, localCountryCode); - return ShortNumberInfo.getInstance().isPossibleShortNumberForRegion(parsedNumber, localCountryCode); - } catch (NumberParseException e) { - return false; - } + return number; } private @Nullable String parseAreaCode(@NonNull String e164Number, int countryCode) { diff --git a/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java index 5ad89598cf..8eb29d3509 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java @@ -1,24 +1,16 @@ package org.thoughtcrime.securesms.database.helpers; -import android.Manifest; 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 android.net.Uri; -import android.provider.ContactsContract; import android.support.annotation.Nullable; import android.text.TextUtils; -import org.thoughtcrime.securesms.logging.Log; import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; -import com.google.i18n.phonenumbers.ShortNumberInfo; import org.thoughtcrime.securesms.DatabaseUpgradeActivity; import org.thoughtcrime.securesms.crypto.AttachmentSecret; @@ -26,7 +18,6 @@ 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.Address; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DraftDatabase; import org.thoughtcrime.securesms.database.GroupDatabase; @@ -37,8 +28,8 @@ 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.notifications.MessageNotifier; -import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.util.Base64; import org.thoughtcrime.securesms.util.DelimiterUtil; import org.thoughtcrime.securesms.util.Hex; @@ -1385,71 +1376,18 @@ public class ClassicOpenHelper extends SQLiteOpenHelper { add("AC"); }}; - private final Phonenumber.PhoneNumber localNumber; private final String localNumberString; - private final String localCountryCode; - private final PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.getInstance(); private final Pattern ALPHA_PATTERN = Pattern.compile("[a-zA-Z]"); public NumberMigrator(String localNumber) { - try { - this.localNumberString = localNumber; - this.localNumber = phoneNumberUtil.parse(localNumber, null); - this.localCountryCode = phoneNumberUtil.getRegionCodeForNumber(this.localNumber); - } catch (NumberParseException e) { - throw new AssertionError(e); - } + this.localNumberString = localNumber; } public String migrate(@Nullable String number) { - if (number == null) return "Unknown"; - if (number.startsWith("__textsecure_group__!")) return number; - if (ALPHA_PATTERN.matcher(number).find()) return number.trim(); - - String bareNumber = number.replaceAll("[^0-9+]", ""); - - if (bareNumber.length() == 0) { - if (TextUtils.isEmpty(number.trim())) return "Unknown"; - else return number.trim(); - } - - // libphonenumber doesn't seem to be correct for Germany and Finland - if (bareNumber.length() <= 6 && ("DE".equals(localCountryCode) || "FI".equals(localCountryCode) || "SK".equals(localCountryCode))) { - return bareNumber; - } - - // libphonenumber seems incorrect for Russia and a few other countries with 4 digit short codes. - if (bareNumber.length() <= 4 && !SHORT_COUNTRIES.contains(localCountryCode)) { - return bareNumber; - } - - try { - Phonenumber.PhoneNumber parsedNumber = phoneNumberUtil.parse(bareNumber, localCountryCode); - - if (ShortNumberInfo.getInstance().isPossibleShortNumberForRegion(parsedNumber, localCountryCode)) { - return bareNumber; - } - - return phoneNumberUtil.format(parsedNumber, PhoneNumberUtil.PhoneNumberFormat.E164); - } catch (NumberParseException e) { - Log.w(TAG, e); - if (bareNumber.charAt(0) == '+') - return bareNumber; - - String localNumberImprecise = localNumberString; - - if (localNumberImprecise.charAt(0) == '+') - localNumberImprecise = localNumberImprecise.substring(1); - - if (localNumberImprecise.length() == bareNumber.length() || bareNumber.length() > localNumberImprecise.length()) - return "+" + number; - - int difference = localNumberImprecise.length() - bareNumber.length(); - - return "+" + localNumberImprecise.substring(0, difference) + bareNumber; - } + if (number == null) return "Unknown"; + return number; } } diff --git a/src/org/thoughtcrime/securesms/database/loaders/CountryListLoader.java b/src/org/thoughtcrime/securesms/database/loaders/CountryListLoader.java index 22b85a19a8..2c36df2a59 100644 --- a/src/org/thoughtcrime/securesms/database/loaders/CountryListLoader.java +++ b/src/org/thoughtcrime/securesms/database/loaders/CountryListLoader.java @@ -1,19 +1,12 @@ package org.thoughtcrime.securesms.database.loaders; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - import android.content.Context; import android.support.v4.content.AsyncTaskLoader; - -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Map; public class CountryListLoader extends AsyncTaskLoader>> { @@ -23,19 +16,7 @@ public class CountryListLoader extends AsyncTaskLoader> loadInBackground() { - Set regions = PhoneNumberUtil.getInstance().getSupportedRegions(); - ArrayList> results = new ArrayList>(regions.size()); - - for (String region : regions) { - Map data = new HashMap(2); - data.put("country_name", PhoneNumberFormatter.getRegionDisplayName(region)); - data.put("country_code", "+" +PhoneNumberUtil.getInstance().getCountryCodeForRegion(region)); - results.add(data); - } - - Collections.sort(results, new RegionComparator()); - - return results; + return new ArrayList<>(); } private static class RegionComparator implements Comparator> { diff --git a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java index 4483e20d2a..9ce2e90786 100644 --- a/src/org/thoughtcrime/securesms/mms/AttachmentManager.java +++ b/src/org/thoughtcrime/securesms/mms/AttachmentManager.java @@ -33,20 +33,12 @@ import android.provider.OpenableColumns; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; - -import org.thoughtcrime.securesms.TransportOption; -import org.thoughtcrime.securesms.mediasend.MediaSendActivity; -import org.thoughtcrime.securesms.logging.Log; import android.util.Pair; import android.view.View; import android.widget.Toast; -import com.google.android.gms.common.GooglePlayServicesNotAvailableException; -import com.google.android.gms.common.GooglePlayServicesRepairableException; -import com.google.android.gms.location.places.ui.PlacePicker; - import org.thoughtcrime.securesms.MediaPreviewActivity; -import network.loki.messenger.R; +import org.thoughtcrime.securesms.TransportOption; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.components.AudioView; import org.thoughtcrime.securesms.components.DocumentView; @@ -55,6 +47,8 @@ import org.thoughtcrime.securesms.components.ThumbnailView; import org.thoughtcrime.securesms.components.location.SignalMapView; import org.thoughtcrime.securesms.components.location.SignalPlace; import org.thoughtcrime.securesms.giph.ui.GiphyActivity; +import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.mediasend.MediaSendActivity; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.providers.DeprecatedPersistentBlobProvider; @@ -77,6 +71,8 @@ import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutionException; +import network.loki.messenger.R; + public class AttachmentManager { diff --git a/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java index 9ec8d17291..094f1fa12e 100644 --- a/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java +++ b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java @@ -14,17 +14,14 @@ import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.preference.CheckBoxPreference; import android.support.v7.preference.Preference; -import org.thoughtcrime.securesms.logging.Log; import android.widget.Toast; -import com.google.firebase.iid.FirebaseInstanceId; - import org.thoughtcrime.securesms.ApplicationPreferencesActivity; import org.thoughtcrime.securesms.LogSubmitActivity; -import network.loki.messenger.R; import org.thoughtcrime.securesms.RegistrationActivity; import org.thoughtcrime.securesms.contacts.ContactAccessor; import org.thoughtcrime.securesms.contacts.ContactIdentityManager; +import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.push.AccountManagerFactory; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask; @@ -34,6 +31,8 @@ import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedE import java.io.IOException; +import network.loki.messenger.R; + public class AdvancedPreferenceFragment extends CorrectedPreferenceFragment { private static final String TAG = AdvancedPreferenceFragment.class.getSimpleName(); @@ -187,15 +186,11 @@ public class AdvancedPreferenceFragment extends CorrectedPreferenceFragment { SignalServiceAccountManager accountManager = AccountManagerFactory.createManager(context); try { - accountManager.setGcmId(Optional.absent()); + accountManager.setGcmId(Optional.absent()); } catch (AuthorizationFailedException e) { Log.w(TAG, e); } - if (!TextSecurePreferences.isFcmDisabled(context)) { - FirebaseInstanceId.getInstance().deleteInstanceId(); - } - return SUCCESS; } catch (IOException ioe) { Log.w(TAG, ioe); diff --git a/src/org/thoughtcrime/securesms/push/AccountManagerFactory.java b/src/org/thoughtcrime/securesms/push/AccountManagerFactory.java index c8729b9ab7..883b5fe315 100644 --- a/src/org/thoughtcrime/securesms/push/AccountManagerFactory.java +++ b/src/org/thoughtcrime/securesms/push/AccountManagerFactory.java @@ -1,15 +1,12 @@ package org.thoughtcrime.securesms.push; import android.content.Context; -import android.os.AsyncTask; -import org.thoughtcrime.securesms.logging.Log; -import com.google.android.gms.security.ProviderInstaller; - -import network.loki.messenger.BuildConfig; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.whispersystems.signalservice.api.SignalServiceAccountManager; +import network.loki.messenger.BuildConfig; + public class AccountManagerFactory { private static final String TAG = AccountManagerFactory.class.getSimpleName(); @@ -22,20 +19,6 @@ public class AccountManagerFactory { } public static SignalServiceAccountManager createManager(final Context context, String number, String password) { - if (new SignalServiceNetworkAccess(context).isCensored(number)) { - new AsyncTask() { - @Override - protected Void doInBackground(Void... params) { - try { - ProviderInstaller.installIfNeeded(context); - } catch (Throwable t) { - Log.w(TAG, t); - } - return null; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - return new SignalServiceAccountManager(new SignalServiceNetworkAccess(context).getConfiguration(number), number, password, BuildConfig.USER_AGENT); } diff --git a/src/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java b/src/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java index da2371aa4d..9ef5b4a0f3 100644 --- a/src/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java +++ b/src/org/thoughtcrime/securesms/stickers/StickerPackPreviewRepository.java @@ -6,7 +6,6 @@ import android.support.annotation.NonNull; import android.support.annotation.WorkerThread; import com.annimon.stream.Stream; -import com.google.android.gms.common.util.Hex; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.database.DatabaseFactory; @@ -15,6 +14,7 @@ import org.thoughtcrime.securesms.database.model.StickerPackRecord; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.util.Hex; import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.util.guava.Optional; @@ -81,8 +81,8 @@ public final class StickerPackPreviewRepository implements InjectableType { @WorkerThread private Optional getManifestRemote(@NonNull String packId, @NonNull String packKey) { try { - byte[] packIdBytes = Hex.stringToBytes(packId); - byte[] packKeyBytes = Hex.stringToBytes(packKey); + byte[] packIdBytes = Hex.fromStringCondensed(packId); + byte[] packKeyBytes = Hex.fromStringCondensed(packKey); SignalServiceStickerManifest remoteManifest = receiver.retrieveStickerManifest(packIdBytes, packKeyBytes); StickerManifest localManifest = new StickerManifest(packId, packKey, diff --git a/src/org/thoughtcrime/securesms/stickers/StickerRemoteUriFetcher.java b/src/org/thoughtcrime/securesms/stickers/StickerRemoteUriFetcher.java index fcb30af9b5..f75c538838 100644 --- a/src/org/thoughtcrime/securesms/stickers/StickerRemoteUriFetcher.java +++ b/src/org/thoughtcrime/securesms/stickers/StickerRemoteUriFetcher.java @@ -5,9 +5,9 @@ import android.support.annotation.NonNull; import com.bumptech.glide.Priority; import com.bumptech.glide.load.DataSource; import com.bumptech.glide.load.data.DataFetcher; -import com.google.android.gms.common.util.Hex; import org.thoughtcrime.securesms.logging.Log; +import org.thoughtcrime.securesms.util.Hex; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; @@ -32,8 +32,8 @@ public final class StickerRemoteUriFetcher implements DataFetcher { @Override public void loadData(@NonNull Priority priority, @NonNull DataCallback callback) { try { - byte[] packIdBytes = Hex.stringToBytes(stickerUri.getPackId()); - byte[] packKeyBytes = Hex.stringToBytes(stickerUri.getPackKey()); + byte[] packIdBytes = Hex.fromStringCondensed(stickerUri.getPackId()); + byte[] packKeyBytes = Hex.fromStringCondensed(stickerUri.getPackKey()); InputStream stream = receiver.retrieveSticker(packIdBytes, packKeyBytes, stickerUri.getStickerId()); callback.onDataReady(stream); diff --git a/src/org/thoughtcrime/securesms/util/PlayServicesUtil.java b/src/org/thoughtcrime/securesms/util/PlayServicesUtil.java deleted file mode 100644 index fe629ba904..0000000000 --- a/src/org/thoughtcrime/securesms/util/PlayServicesUtil.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.thoughtcrime.securesms.util; - - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import org.thoughtcrime.securesms.logging.Log; - -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GoogleApiAvailability; - -public class PlayServicesUtil { - - private static final String TAG = PlayServicesUtil.class.getSimpleName(); - - public enum PlayServicesStatus { - SUCCESS, - MISSING, - NEEDS_UPDATE, - TRANSIENT_ERROR - } - - public static PlayServicesStatus getPlayServicesStatus(Context context) { - int gcmStatus = 0; - - try { - gcmStatus = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context); - } catch (Throwable t) { - Log.w(TAG, t); - return PlayServicesStatus.MISSING; - } - - Log.i(TAG, "Play Services: " + gcmStatus); - - switch (gcmStatus) { - case ConnectionResult.SUCCESS: - return PlayServicesStatus.SUCCESS; - case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: - try { - ApplicationInfo applicationInfo = context.getPackageManager().getApplicationInfo("com.google.android.gms", 0); - - if (applicationInfo != null && !applicationInfo.enabled) { - return PlayServicesStatus.MISSING; - } - } catch (PackageManager.NameNotFoundException e) { - Log.w(TAG, e); - } - - return PlayServicesStatus.NEEDS_UPDATE; - case ConnectionResult.SERVICE_DISABLED: - case ConnectionResult.SERVICE_MISSING: - case ConnectionResult.SERVICE_INVALID: - case ConnectionResult.API_UNAVAILABLE: - case ConnectionResult.SERVICE_MISSING_PERMISSION: - return PlayServicesStatus.MISSING; - default: - return PlayServicesStatus.TRANSIENT_ERROR; - } - } - -} diff --git a/src/org/thoughtcrime/securesms/util/ShortCodeUtil.java b/src/org/thoughtcrime/securesms/util/ShortCodeUtil.java index a119213feb..8a4a9d9018 100644 --- a/src/org/thoughtcrime/securesms/util/ShortCodeUtil.java +++ b/src/org/thoughtcrime/securesms/util/ShortCodeUtil.java @@ -2,13 +2,6 @@ package org.thoughtcrime.securesms.util; import android.support.annotation.NonNull; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; -import com.google.i18n.phonenumbers.ShortNumberInfo; - -import org.thoughtcrime.securesms.logging.Log; - import java.util.HashSet; import java.util.Set; @@ -24,23 +17,7 @@ public class ShortCodeUtil { }}; public static boolean isShortCode(@NonNull String localNumber, @NonNull String number) { - try { - PhoneNumberUtil util = PhoneNumberUtil.getInstance(); - Phonenumber.PhoneNumber localNumberObject = util.parse(localNumber, null); - String localCountryCode = util.getRegionCodeForNumber(localNumberObject); - String bareNumber = number.replaceAll("[^0-9+]", ""); - - // libphonenumber seems incorrect for Russia and a few other countries with 4 digit short codes. - if (bareNumber.length() <= 4 && !SHORT_COUNTRIES.contains(localCountryCode)) { - return true; - } - - Phonenumber.PhoneNumber shortCode = util.parse(number, localCountryCode); - return ShortNumberInfo.getInstance().isPossibleShortNumberForRegion(shortCode, localCountryCode); - } catch (NumberParseException e) { - Log.w(TAG, e); - return false; - } + return false; } } diff --git a/src/org/thoughtcrime/securesms/util/Util.java b/src/org/thoughtcrime/securesms/util/Util.java index 24cfc6ba11..159cf26586 100644 --- a/src/org/thoughtcrime/securesms/util/Util.java +++ b/src/org/thoughtcrime/securesms/util/Util.java @@ -32,20 +32,14 @@ import android.os.Looper; import android.provider.Telephony; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.annotation.RequiresPermission; import android.telephony.TelephonyManager; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.StyleSpan; -import com.google.android.mms.pdu_alt.CharacterSets; import com.google.android.mms.pdu_alt.EncodedStringValue; -import com.google.i18n.phonenumbers.NumberParseException; -import com.google.i18n.phonenumbers.PhoneNumberUtil; -import com.google.i18n.phonenumbers.Phonenumber; -import network.loki.messenger.BuildConfig; import org.thoughtcrime.securesms.components.ComposeText; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.logging.Log; @@ -58,7 +52,7 @@ import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.text.DecimalFormat; import java.util.ArrayList; @@ -73,6 +67,8 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import network.loki.messenger.BuildConfig; + public class Util { private static final String TAG = Util.class.getSimpleName(); @@ -170,27 +166,15 @@ public class Util { } public static @NonNull String toIsoString(byte[] bytes) { - try { - return new String(bytes, CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - throw new AssertionError("ISO_8859_1 must be supported!"); - } + return new String(bytes, StandardCharsets.ISO_8859_1); } public static byte[] toIsoBytes(String isoString) { - try { - return isoString.getBytes(CharacterSets.MIMENAME_ISO_8859_1); - } catch (UnsupportedEncodingException e) { - throw new AssertionError("ISO_8859_1 must be supported!"); - } + return isoString.getBytes(StandardCharsets.ISO_8859_1); } public static byte[] toUtf8Bytes(String utf8String) { - try { - return utf8String.getBytes(CharacterSets.MIMENAME_UTF_8); - } catch (UnsupportedEncodingException e) { - throw new AssertionError("UTF_8 must be supported!"); - } + return utf8String.getBytes(StandardCharsets.UTF_8); } public static void wait(Object lock, long timeout) { @@ -279,27 +263,6 @@ public class Util { return total; } - @RequiresPermission(anyOf = { - android.Manifest.permission.READ_PHONE_STATE, - android.Manifest.permission.READ_SMS, - android.Manifest.permission.READ_PHONE_NUMBERS - }) - @SuppressLint("MissingPermission") - public static Optional getDeviceNumber(Context context) { - try { - final String localNumber = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getLine1Number(); - final Optional countryIso = getSimCountryIso(context); - - if (TextUtils.isEmpty(localNumber)) return Optional.absent(); - if (!countryIso.isPresent()) return Optional.absent(); - - return Optional.fromNullable(PhoneNumberUtil.getInstance().parse(localNumber, countryIso.get())); - } catch (NumberParseException e) { - Log.w(TAG, e); - return Optional.absent(); - } - } - public static Optional getSimCountryIso(Context context) { String simCountryIso = ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).getSimCountryIso(); return Optional.fromNullable(simCountryIso != null ? simCountryIso.toUpperCase() : null); From 597b7f157c4b7885ca02b167057c2bb7d0dfb2c2 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 28 Feb 2020 09:04:57 +0700 Subject: [PATCH 10/13] Move file --- .../securesms/jobs/PushDecryptJob.java | 4 ++-- .../loki/MultiDeviceOpenGroupUpdateJob.kt | 15 ++++++--------- .../activities/JoinPublicChatActivity.kt | 2 +- .../utilities}/OpenGroupUtilities.kt | 18 ++++++++---------- 4 files changed, 17 insertions(+), 22 deletions(-) rename src/org/thoughtcrime/securesms/loki/{ => redesign/utilities}/OpenGroupUtilities.kt (83%) diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index af5adc43f1..4fc2508de9 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -73,7 +73,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.LokiSessionResetImplementation; import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; -import org.thoughtcrime.securesms.loki.OpenGroupUtilities; +import org.thoughtcrime.securesms.loki.redesign.utilities.OpenGroupUtilities; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities; import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase; @@ -764,7 +764,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { String url = openGroup.getServer(); long channel = openGroup.getChannel(); OpenGroupUtilities.addGroup(context, url, channel).fail(e -> { - Log.d("Loki", "Failed to sync open group " + url + " due to error: " + e + "."); + Log.d("Loki", "Failed to sync open group: " + url + " due to error: " + e + "."); return Unit.INSTANCE; }); } diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt index 38ee04790b..0ef7ca67ed 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt @@ -17,9 +17,9 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType { + companion object { const val KEY = "MultiDeviceGroupUpdateJob" - private val TAG = MultiDeviceOpenGroupUpdateJob::class.java.simpleName } @Inject @@ -32,18 +32,14 @@ class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) .setMaxAttempts(Parameters.UNLIMITED) .build()) - override fun getFactoryKey(): String { - return KEY - } + override fun getFactoryKey(): String { return KEY } - override fun serialize(): Data { - return Data.EMPTY - } + override fun serialize(): Data { return Data.EMPTY } @Throws(Exception::class) public override fun onRun() { if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting...") + Log.d("Loki", "Not multi device; aborting...") return } @@ -65,7 +61,7 @@ class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) messageSender.sendMessage(0, SignalServiceSyncMessage.forOpenGroups(openGroups), UnidentifiedAccessUtil.getAccessForSync(context)) } else { - Log.d(TAG, "No open groups to sync.") + Log.d("Loki", "No open groups to sync.") } } @@ -76,6 +72,7 @@ class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) override fun onCanceled() { } class Factory : Job.Factory { + override fun create(parameters: Parameters, data: Data): MultiDeviceOpenGroupUpdateJob { return MultiDeviceOpenGroupUpdateJob(parameters) } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt index a7f4b69bc7..9364419d24 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt @@ -18,7 +18,7 @@ import nl.komponents.kovenant.ui.failUi import nl.komponents.kovenant.ui.successUi import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity -import org.thoughtcrime.securesms.loki.OpenGroupUtilities +import org.thoughtcrime.securesms.loki.redesign.utilities.OpenGroupUtilities import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragment import org.thoughtcrime.securesms.loki.redesign.fragments.ScanQRCodeWrapperFragmentDelegate import org.thoughtcrime.securesms.sms.MessageSender diff --git a/src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt b/src/org/thoughtcrime/securesms/loki/redesign/utilities/OpenGroupUtilities.kt similarity index 83% rename from src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt rename to src/org/thoughtcrime/securesms/loki/redesign/utilities/OpenGroupUtilities.kt index ae47fb25da..87f7afdf6b 100644 --- a/src/org/thoughtcrime/securesms/loki/OpenGroupUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/utilities/OpenGroupUtilities.kt @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.loki +package org.thoughtcrime.securesms.loki.redesign.utilities import android.content.Context import nl.komponents.kovenant.Promise @@ -11,19 +11,17 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.loki.api.LokiPublicChat object OpenGroupUtilities { - @JvmStatic fun addGroup(context: Context, url: String, channel: Long): Promise { - // Check if we have an existing group - val groupId = LokiPublicChat.getId(channel, url) - val threadID = GroupManager.getPublicChatThreadId(groupId, context) - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) - if (openGroup != null) { - return Promise.of(openGroup) - } + @JvmStatic fun addGroup(context: Context, url: String, channel: Long): Promise { + // Check for an existing group + val groupID = LokiPublicChat.getId(channel, url) + val threadID = GroupManager.getPublicChatThreadId(groupID, context) + val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) + if (openGroup != null) { return Promise.of(openGroup) } // Add the new group val application = ApplicationContext.getInstance(context) val displayName = TextSecurePreferences.getProfileName(context) - val lokiPublicChatAPI = application.lokiPublicChatAPI ?: throw Error("LokiPublicChatAPI is not initialized") + val lokiPublicChatAPI = application.lokiPublicChatAPI ?: throw Error("LokiPublicChatAPI is not initialized.") return application.lokiPublicChatManager.addChat(url, channel).then { group -> DatabaseFactory.getLokiAPIDatabase(context).removeLastMessageServerID(channel, url) DatabaseFactory.getLokiAPIDatabase(context).removeLastDeletionServerID(channel, url) From be8abcc2889fdc766076de935b32e8eb36473a80 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 28 Feb 2020 09:07:58 +0700 Subject: [PATCH 11/13] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 4b62fc423f..a918936f20 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ obj/ jni/libspeex/.deps/ *.sh pkcs11.password +fabric.properties +play From 2fdd9bfe3eadc8b88f164b40b3a6eb9648e5baa0 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Tue, 3 Mar 2020 14:29:40 +1100 Subject: [PATCH 12/13] fix syncing contacts and closed groups after device linking --- .../securesms/jobs/MultiDeviceContactUpdateJob.java | 2 +- .../securesms/loki/MultiDeviceOpenGroupUpdateJob.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index aa22fa51e5..7fde014469 100644 --- a/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/src/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -245,7 +245,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableTy } private List getAllContacts() { - List
contactAddresses = DatabaseFactory.getRecipientDatabase(context).getRegistered(); + List
contactAddresses = new ArrayList<>(DatabaseFactory.getRecipientDatabase(context).getAllAddresses()); List contacts = new ArrayList<>(contactAddresses.size()); for (Address address : contactAddresses) { if (!address.isPhone()) { continue; } diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt index 0ef7ca67ed..683eea84b6 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceOpenGroupUpdateJob.kt @@ -19,7 +19,7 @@ import javax.inject.Inject class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType { companion object { - const val KEY = "MultiDeviceGroupUpdateJob" + const val KEY = "MultiDeviceOpenGroupUpdateJob" } @Inject @@ -27,7 +27,7 @@ class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) constructor() : this(Parameters.Builder() .addConstraint(NetworkConstraint.KEY) - .setQueue("MultiDeviceGroupUpdateJob") + .setQueue("MultiDeviceOpenGroupUpdateJob") .setLifespan(TimeUnit.DAYS.toMillis(1)) .setMaxAttempts(Parameters.UNLIMITED) .build()) From 218d6488af2651f5a1b79485336483addc8728ad Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 4 Mar 2020 09:51:38 +1100 Subject: [PATCH 13/13] Update version number --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 853e76e084..777b7cbc38 100644 --- a/build.gradle +++ b/build.gradle @@ -184,8 +184,8 @@ dependencies { implementation "com.github.ybq:Android-SpinKit:1.4.0" } -def canonicalVersionCode = 38 -def canonicalVersionName = "1.0.4" +def canonicalVersionCode = 39 +def canonicalVersionName = "1.0.5" def postFixSize = 10 def abiPostFix = ['armeabi-v7a' : 1,