From 0ed7b28b6b1c42686c09ba872231c1cb12210f0f Mon Sep 17 00:00:00 2001 From: jubb Date: Thu, 29 Jul 2021 17:02:58 +1000 Subject: [PATCH] refactor: performance experiments --- app/build.gradle | 4 +- .../securesms/ApplicationContext.java | 17 +++-- .../conversation/v2/ConversationActivityV2.kt | 2 +- .../conversation/v2/messages/QuoteView.kt | 3 +- .../v2/messages/VisibleMessageContentView.kt | 2 +- .../v2/utilities/MentionUtilities.kt | 11 ++- .../securesms/home/ConversationView.kt | 2 +- .../securesms/home/HomeActivity.kt | 67 +++++++++++-------- .../longmessage/LongMessageActivity.java | 2 +- .../notifications/DefaultMessageNotifier.java | 6 +- app/src/main/res/layout/activity_home.xml | 7 +- .../main/res/layout/seed_reminder_stub.xml | 6 ++ 12 files changed, 72 insertions(+), 57 deletions(-) create mode 100644 app/src/main/res/layout/seed_reminder_stub.xml diff --git a/app/build.gradle b/app/build.gradle index df68180146..9a9d61e97f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,7 +35,6 @@ dependencies { implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation 'androidx.exifinterface:exifinterface:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.1' - implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' implementation 'androidx.lifecycle:lifecycle-common-java8:2.3.1' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' @@ -96,7 +95,7 @@ dependencies { } implementation 'com.codewaves.stickyheadergrid:stickyheadergrid:0.9.4' implementation 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3-S2' - implementation 'net.zetetic:android-database-sqlcipher:4.4.3' + implementation 'org.signal:android-database-sqlcipher:3.5.9-S3' implementation ('com.googlecode.ez-vcard:ez-vcard:0.9.11') { exclude group: 'com.fasterxml.jackson.core' exclude group: 'org.freemarker' @@ -214,7 +213,6 @@ android { buildTypes { release { - debuggable true minifyEnabled false } debug { diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index e2c82814e3..363343696c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -15,6 +15,7 @@ */ package org.thoughtcrime.securesms; +import android.app.Application; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; @@ -26,7 +27,6 @@ import androidx.annotation.NonNull; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner; -import androidx.multidex.MultiDexApplication; import org.conscrypt.Conscrypt; import org.session.libsession.avatars.AvatarHelper; @@ -104,7 +104,7 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; * * @author Moxie Marlinspike */ -public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver { +public class ApplicationContext extends Application implements DependencyInjector, DefaultLifecycleObserver { public static final String PREFERENCES_NAME = "SecureSMS-Preferences"; @@ -180,12 +180,15 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc Log.i(TAG, "App is now visible."); KeyCachingService.onAppForegrounded(this); - if (poller != null) { - poller.setCaughtUp(false); - } - startPollingIfNeeded(); + ThreadUtils.queue(()->{ + if (poller != null) { + poller.setCaughtUp(false); + } - OpenGroupManager.INSTANCE.startPolling(); + startPollingIfNeeded(); + + OpenGroupManager.INSTANCE.startPolling(); + }); } @Override diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 656da5fd66..f09b7cdf64 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -1206,7 +1206,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val sortedMessages = messages.sortedBy { it.dateSent } val builder = StringBuilder() for (message in sortedMessages) { - val body = MentionUtilities.highlightMentions(message.body, message.threadId, this) + val body = MentionUtilities.highlightMentions(message.body, this) if (TextUtils.isEmpty(body)) { continue } val formattedTimestamp = DateUtils.getDisplayFormattedTimeSpanString(this, Locale.getDefault(), message.timestamp) builder.append("$formattedTimestamp: $body").append('\n') diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt index 1798b07f0a..aa649743ea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/QuoteView.kt @@ -10,7 +10,6 @@ import androidx.annotation.ColorInt import androidx.core.content.res.ResourcesCompat import androidx.core.text.toSpannable import androidx.core.view.isVisible -import kotlinx.android.synthetic.main.view_link_preview.view.* import kotlinx.android.synthetic.main.view_quote.view.* import network.loki.messenger.R import org.session.libsession.messaging.contacts.Contact @@ -120,7 +119,7 @@ class QuoteView : LinearLayout { } quoteViewAuthorTextView.isVisible = thread.isGroupRecipient // Body - quoteViewBodyTextView.text = if (isOpenGroupInvitation) resources.getString(R.string.open_group_invitation_view__open_group_invitation) else MentionUtilities.highlightMentions((body ?: "").toSpannable(), threadID, context); + quoteViewBodyTextView.text = if (isOpenGroupInvitation) resources.getString(R.string.open_group_invitation_view__open_group_invitation) else MentionUtilities.highlightMentions((body ?: "").toSpannable(), context); quoteViewBodyTextView.setTextColor(getTextColor(isOutgoingMessage)) // Accent line / attachment preview val hasAttachments = (attachments != null && attachments.asAttachments().isNotEmpty()) && !isOriginalMissing diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index ec55af5427..26d7b0905f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -223,7 +223,7 @@ class VisibleMessageContentView : LinearLayout { body.setSpan(replacementSpan, start, end, flags) } - body = MentionUtilities.highlightMentions(body, message.isOutgoing, message.threadId, context) + body = MentionUtilities.highlightMentions(body, message.isOutgoing, context) body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { BackgroundColorSpan(Color.WHITE) }, body, searchQuery) body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { ForegroundColorSpan(Color.BLACK) }, body, searchQuery) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt index 3a0c6e7c15..614414b88b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/utilities/MentionUtilities.kt @@ -19,15 +19,13 @@ import java.util.regex.Pattern object MentionUtilities { @JvmStatic - fun highlightMentions(text: CharSequence, threadID: Long, context: Context): String { - return highlightMentions(text, false, threadID, context).toString() // isOutgoingMessage is irrelevant + fun highlightMentions(text: CharSequence, context: Context): String { + return highlightMentions(text, false, context).toString() // isOutgoingMessage is irrelevant } @JvmStatic - fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, threadID: Long, context: Context): SpannableString { + fun highlightMentions(text: CharSequence, isOutgoingMessage: Boolean, context: Context): SpannableString { @Suppress("NAME_SHADOWING") var text = text - val threadDB = DatabaseFactory.getThreadDatabase(context) - val isOpenGroup = threadDB.getRecipientForThreadId(threadID)?.isOpenGroupRecipient ?: false val pattern = Pattern.compile("@[0-9a-fA-F]*") var matcher = pattern.matcher(text) val mentions = mutableListOf, String>>() @@ -40,8 +38,7 @@ object MentionUtilities { TextSecurePreferences.getProfileName(context) } else { val contact = DatabaseFactory.getSessionContactDatabase(context).getContactWithSessionID(publicKey) - @Suppress("NAME_SHADOWING") val context = if (isOpenGroup) Contact.ContactContext.OPEN_GROUP else Contact.ContactContext.REGULAR - contact?.displayName(context) + contact?.displayName(Contact.ContactContext.REGULAR) } if (userDisplayName != null) { text = text.subSequence(0, matcher.start()).toString() + "@" + userDisplayName + text.subSequence(matcher.end(), text.length) diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt index 9454070e77..a5d4c1d87d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -69,7 +69,7 @@ class ConversationView : LinearLayout { } muteIndicatorImageView.setImageResource(drawableRes) val rawSnippet = thread.getDisplayBody(context) - val snippet = highlightMentions(rawSnippet, thread.threadId, context) + val snippet = highlightMentions(rawSnippet, context) snippetTextView.text = snippet snippetTextView.typeface = if (unreadCount > 0) Typeface.DEFAULT_BOLD else Typeface.DEFAULT snippetTextView.visibility = if (isTyping) View.GONE else View.VISIBLE diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index e03d25d270..80e91a85db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -12,6 +12,7 @@ import android.text.SpannableString import android.text.style.ForegroundColorSpan import android.view.View import android.widget.Toast +import androidx.core.view.isVisible import androidx.lifecycle.Observer import androidx.lifecycle.lifecycleScope import androidx.loader.app.LoaderManager @@ -19,9 +20,11 @@ import androidx.loader.content.Loader import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.android.synthetic.main.activity_home.* +import kotlinx.android.synthetic.main.seed_reminder_stub.view.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import network.loki.messenger.R import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe @@ -63,8 +66,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis // region Lifecycle override fun onCreate(savedInstanceState: Bundle?, isReady: Boolean) { super.onCreate(savedInstanceState, isReady) - // Double check that the long poller is up - (applicationContext as ApplicationContext).startPollingIfNeeded() // Set content view setContentView(R.layout.activity_home) // Set custom toolbar @@ -79,14 +80,18 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis // Set up seed reminder view val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this) if (!hasViewedSeed) { - val seedReminderViewTitle = SpannableString("You're almost finished! 80%") // Intentionally not yet translated - seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) - seedReminderView.title = seedReminderViewTitle - seedReminderView.subtitle = resources.getString(R.string.view_seed_reminder_subtitle_1) - seedReminderView.setProgress(80, false) - seedReminderView.delegate = this + seedReminderStub.isVisible = true + seedReminderStub.apply { + val seedReminderView = this.seedReminderView + val seedReminderViewTitle = SpannableString("You're almost finished! 80%") // Intentionally not yet translated + seedReminderViewTitle.setSpan(ForegroundColorSpan(resources.getColorWithID(R.color.accent, theme)), 24, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) + seedReminderView.title = seedReminderViewTitle + seedReminderView.subtitle = resources.getString(R.string.view_seed_reminder_subtitle_1) + seedReminderView.setProgress(80, false) + seedReminderView.delegate = this@HomeActivity + } } else { - seedReminderView.visibility = View.GONE + seedReminderStub.isVisible = false } // Set up recycler view val cursor = DatabaseFactory.getThreadDatabase(this).conversationList @@ -126,24 +131,30 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis this.broadcastReceiver = broadcastReceiver LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, IntentFilter("blockedContactsChanged")) lifecycleScope.launchWhenResumed { - // update things based on TextSecurePrefs (profile info etc) - // Set up typing observer - ApplicationContext.getInstance(this@HomeActivity).typingStatusRepository.typingThreads.observe(this@HomeActivity, Observer> { threadIDs -> - val adapter = recyclerView.adapter as HomeAdapter - adapter.typingThreadIDs = threadIDs ?: setOf() - }) - // Set up remaining components if needed - val application = ApplicationContext.getInstance(this@HomeActivity) - application.registerForFCMIfNeeded(false) - val userPublicKey = TextSecurePreferences.getLocalNumber(this@HomeActivity) - if (userPublicKey != null) { - OpenGroupManager.startPolling() - JobQueue.shared.resumePendingJobs() - } - updateProfileButton() - IP2Country.configureIfNeeded(this@HomeActivity) - TextSecurePreferences.events.filter { it == TextSecurePreferences.PROFILE_NAME_PREF }.collect { - updateProfileButton() + launch(Dispatchers.IO) { + // Double check that the long poller is up + (applicationContext as ApplicationContext).startPollingIfNeeded() + // update things based on TextSecurePrefs (profile info etc) + // Set up typing observer + withContext(Dispatchers.Main) { + ApplicationContext.getInstance(this@HomeActivity).typingStatusRepository.typingThreads.observe(this@HomeActivity, Observer> { threadIDs -> + val adapter = recyclerView.adapter as HomeAdapter + adapter.typingThreadIDs = threadIDs ?: setOf() + }) + updateProfileButton() + TextSecurePreferences.events.filter { it == TextSecurePreferences.PROFILE_NAME_PREF }.collect { + updateProfileButton() + } + } + // Set up remaining components if needed + val application = ApplicationContext.getInstance(this@HomeActivity) + application.registerForFCMIfNeeded(false) + val userPublicKey = TextSecurePreferences.getLocalNumber(this@HomeActivity) + if (userPublicKey != null) { + OpenGroupManager.startPolling() + JobQueue.shared.resumePendingJobs() + } + IP2Country.configureIfNeeded(this@HomeActivity) } } EventBus.getDefault().register(this@HomeActivity) @@ -158,7 +169,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), ConversationClickLis profileButton.update() val hasViewedSeed = TextSecurePreferences.getHasViewedSeed(this) if (hasViewedSeed) { - seedReminderView.visibility = View.GONE + seedReminderStub.visibility = View.GONE } if (TextSecurePreferences.getConfigurationMessageSynced(this)) { lifecycleScope.launch(Dispatchers.IO) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageActivity.java b/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageActivity.java index 04edf1194a..49fc990500 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/longmessage/LongMessageActivity.java @@ -83,7 +83,7 @@ public class LongMessageActivity extends PassphraseRequiredActionBarActivity { } String trimmedBody = getTrimmedBody(message.get().getFullBody()); - String mentionBody = MentionUtilities.highlightMentions(trimmedBody, message.get().getMessageRecord().getThreadId(), this); + String mentionBody = MentionUtilities.highlightMentions(trimmedBody, this); textBody.setText(mentionBody); textBody.setMovementMethod(LinkMovementMethod.getInstance()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java index bdcf916dd4..a08eb1a79f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/DefaultMessageNotifier.java @@ -324,7 +324,7 @@ public class DefaultMessageNotifier implements MessageNotifier { builder.setThread(notifications.get(0).getRecipient()); builder.setMessageCount(notificationState.getMessageCount()); builder.setPrimaryMessageBody(recipient, notifications.get(0).getIndividualRecipient(), - MentionUtilities.highlightMentions(notifications.get(0).getText(), notifications.get(0).getThreadId(), context), + MentionUtilities.highlightMentions(notifications.get(0).getText(), context), notifications.get(0).getSlideDeck()); builder.setContentIntent(notifications.get(0).getPendingIntent(context)); builder.setDeleteIntent(notificationState.getDeleteIntent(context)); @@ -400,13 +400,13 @@ public class DefaultMessageNotifier implements MessageNotifier { while(iterator.hasPrevious()) { NotificationItem item = iterator.previous(); builder.addMessageBody(item.getIndividualRecipient(), item.getRecipient(), - MentionUtilities.highlightMentions(item.getText(), item.getThreadId(), context)); + MentionUtilities.highlightMentions(item.getText(), context)); } if (signal) { builder.setAlarms(notificationState.getRingtone(context), notificationState.getVibrate()); builder.setTicker(notifications.get(0).getIndividualRecipient(), - MentionUtilities.highlightMentions(notifications.get(0).getText(), notifications.get(0).getThreadId(), context)); + MentionUtilities.highlightMentions(notifications.get(0).getText(), context)); } Notification notification = builder.build(); diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 4a3e300d94..87bd87eb2d 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -70,10 +70,11 @@ android:background="?android:dividerHorizontal" android:elevation="1dp" /> - + android:layout_height="wrap_content"/> diff --git a/app/src/main/res/layout/seed_reminder_stub.xml b/app/src/main/res/layout/seed_reminder_stub.xml new file mode 100644 index 0000000000..39a84ac86a --- /dev/null +++ b/app/src/main/res/layout/seed_reminder_stub.xml @@ -0,0 +1,6 @@ + + \ No newline at end of file