load currently open conversation faster

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java  |  1 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 35 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        |  3 
src/main/java/eu/siacs/conversations/utils/QuickLoader.java              | 62 
4 files changed, 84 insertions(+), 17 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -105,6 +105,7 @@ import eu.siacs.conversations.utils.MimeUtils;
 import eu.siacs.conversations.utils.OnPhoneContactsLoadedListener;
 import eu.siacs.conversations.utils.PRNGFixes;
 import eu.siacs.conversations.utils.PhoneHelper;
+import eu.siacs.conversations.utils.QuickLoader;
 import eu.siacs.conversations.utils.ReplacingSerialSingleThreadExecutor;
 import eu.siacs.conversations.utils.ReplacingTaskManager;
 import eu.siacs.conversations.utils.Resolver;
@@ -1392,22 +1393,17 @@ public class XmppConnectionService extends Service {
 				loadPhoneContacts();
 				Log.d(Config.LOGTAG, "restoring messages...");
 				final long startMessageRestore = SystemClock.elapsedRealtime();
-				for (Conversation conversation : conversations) {
-					conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
-					checkDeletedFiles(conversation);
-					conversation.findUnsentTextMessages(new Conversation.OnMessageFound() {
-
-						@Override
-						public void onMessageFound(Message message) {
-							markMessage(message, Message.STATUS_WAITING);
-						}
-					});
-					conversation.findUnreadMessages(new Conversation.OnMessageFound() {
-						@Override
-						public void onMessageFound(Message message) {
-							mNotificationService.pushFromBacklog(message);
-						}
-					});
+				final Conversation quickLoad = QuickLoader.get(this.conversations);
+				if (quickLoad != null) {
+					restoreMessages(quickLoad);
+					updateConversationUi();
+					final long diffMessageRestore = SystemClock.elapsedRealtime() - startMessageRestore;
+					Log.d(Config.LOGTAG,"quickly restored "+quickLoad.getName()+" after " + diffMessageRestore + "ms");
+				}
+				for (Conversation conversation : this.conversations) {
+					if (quickLoad != conversation) {
+						restoreMessages(conversation);
+					}
 				}
 				mNotificationService.finishBacklog(false);
 				restoredFromDatabaseLatch.countDown();
@@ -1419,6 +1415,13 @@ public class XmppConnectionService extends Service {
 		}
 	}
 
+	private void restoreMessages(Conversation conversation) {
+		conversation.addAll(0, databaseBackend.getMessages(conversation, Config.PAGE_SIZE));
+		checkDeletedFiles(conversation);
+		conversation.findUnsentTextMessages(message -> markMessage(message, Message.STATUS_WAITING));
+		conversation.findUnreadMessages(message -> mNotificationService.pushFromBacklog(message));
+	}
+
 	public void loadPhoneContacts() {
 		mContactMergerExecutor.execute(() -> PhoneHelper.loadPhoneContacts(XmppConnectionService.this, new OnPhoneContactsLoadedListener() {
 			@Override

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -95,6 +95,7 @@ import eu.siacs.conversations.ui.widget.EditMessage;
 import eu.siacs.conversations.utils.ExceptionHelper;
 import eu.siacs.conversations.utils.MessageUtils;
 import eu.siacs.conversations.utils.NickValidityChecker;
+import eu.siacs.conversations.utils.QuickLoader;
 import eu.siacs.conversations.utils.StylingHelper;
 import eu.siacs.conversations.utils.TimeframeUtils;
 import eu.siacs.conversations.utils.UIHelper;
@@ -1805,6 +1806,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 		String uuid = savedInstanceState.getString(STATE_CONVERSATION_UUID);
 		pendingLastMessageUuid.push(savedInstanceState.getString(STATE_LAST_MESSAGE_UUID, null));
 		if (uuid != null) {
+			QuickLoader.set(uuid);
 			this.pendingConversationsUuid.push(uuid);
 			String takePhotoUri = savedInstanceState.getString(STATE_PHOTO_URI);
 			if (takePhotoUri != null) {
@@ -1874,6 +1876,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
 	}
 
 	public void reInit(Conversation conversation, Bundle extras) {
+		QuickLoader.set(conversation.getUuid());
 		this.saveMessageDraftStopAudioPlayer();
 		if (this.reInit(conversation, extras != null)) {
 			if (extras != null) {

src/main/java/eu/siacs/conversations/utils/QuickLoader.java 🔗

@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018, Daniel Gultsch All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package eu.siacs.conversations.utils;
+
+
+import java.util.List;
+
+import eu.siacs.conversations.entities.Conversation;
+
+public class QuickLoader {
+
+	private static String CONVERSATION_UUID = null;
+	private static Object LOCK = new Object();
+
+	public static void set(final String uuid) {
+		synchronized (LOCK) {
+			CONVERSATION_UUID = uuid;
+		}
+	}
+
+	public static Conversation get(List<Conversation> haystack) {
+		synchronized (LOCK) {
+			if (CONVERSATION_UUID == null) {
+				return null;
+			}
+			for (Conversation conversation : haystack) {
+				if (conversation.getUuid().equals(CONVERSATION_UUID)) {
+					return conversation;
+				}
+			}
+		}
+		return null;
+	}
+
+}