From e69d944f111b4556120383e8f1c159afebd982e9 Mon Sep 17 00:00:00 2001 From: Alex Hart Date: Mon, 18 Jul 2022 10:18:54 -0300 Subject: [PATCH] Add logging for unread thread ids. --- .../securesms/database/ThreadDatabase.java | 25 +++++++++++-------- .../tabs/ConversationListTabRepository.kt | 17 +++++++++++-- .../java/org/signal/core/util/CursorUtil.java | 10 ++++++++ .../main/java/org/signal/core/util/SqlUtil.kt | 3 +++ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java index f371397e3..9d3092b0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java @@ -25,6 +25,7 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.arch.core.util.Function; import com.annimon.stream.Collectors; import com.annimon.stream.Stream; @@ -516,17 +517,21 @@ public class ThreadDatabase extends Database { } } - public long getUnreadThreadCount() { - SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - String[] projection = SqlUtil.buildArgs("COUNT(*)"); - String where = READ + " != " + ReadStatus.READ.serialize() + " AND " + ARCHIVED + " = 0 AND " + MEANINGFUL_MESSAGES + " != 0"; + public @NonNull Long getUnreadThreadCount() { + return getUnreadThreadIdAggregate(SqlUtil.COUNT, cursor -> CursorUtil.getAggregateOrDefault(cursor, 0L, cursor::getLong)); + } - try (Cursor cursor = db.query(TABLE_NAME, projection, where, null, null, null, null)) { - if (cursor != null && cursor.moveToFirst()) { - return cursor.getLong(0); - } else { - return 0; - } + public @Nullable String getUnreadThreadIdList() { + return getUnreadThreadIdAggregate(SqlUtil.buildArgs("GROUP_CONCAT(" + ID + ")"), + cursor -> CursorUtil.getAggregateOrDefault(cursor, null, cursor::getString)); + } + + private @NonNull T getUnreadThreadIdAggregate(@NonNull String[] aggregator, @NonNull Function mapCursorToType) { + SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); + String where = READ + " != " + ReadStatus.READ.serialize() + " AND " + ARCHIVED + " = 0 AND " + MEANINGFUL_MESSAGES + " != 0"; + + try (Cursor cursor = db.query(TABLE_NAME, aggregator, where, null, null, null, null)) { + return mapCursorToType.apply(cursor); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabRepository.kt index d94272571..eb04c817d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/stories/tabs/ConversationListTabRepository.kt @@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.stories.tabs import io.reactivex.rxjava3.core.Observable import io.reactivex.rxjava3.schedulers.Schedulers +import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.database.DatabaseObserver import org.thoughtcrime.securesms.database.SignalDatabase import org.thoughtcrime.securesms.dependencies.ApplicationDependencies @@ -9,15 +10,27 @@ import org.thoughtcrime.securesms.recipients.Recipient class ConversationListTabRepository { + companion object { + private val TAG = Log.tag(ConversationListTabRepository::class.java) + } + fun getNumberOfUnreadConversations(): Observable { return Observable.create { - val listener = DatabaseObserver.Observer { + fun refresh() { it.onNext(SignalDatabase.threads.unreadThreadCount) + + val ids = SignalDatabase.threads.unreadThreadIdList + Log.d(TAG, "Unread threads: { $ids }") + } + + val listener = DatabaseObserver.Observer { + refresh() } ApplicationDependencies.getDatabaseObserver().registerConversationListObserver(listener) it.setCancellable { ApplicationDependencies.getDatabaseObserver().unregisterObserver(listener) } - it.onNext(SignalDatabase.threads.unreadThreadCount) + + refresh() }.subscribeOn(Schedulers.io()) } diff --git a/core-util/src/main/java/org/signal/core/util/CursorUtil.java b/core-util/src/main/java/org/signal/core/util/CursorUtil.java index 62aa5f57b..a319556f2 100644 --- a/core-util/src/main/java/org/signal/core/util/CursorUtil.java +++ b/core-util/src/main/java/org/signal/core/util/CursorUtil.java @@ -3,8 +3,10 @@ package org.signal.core.util; import android.database.Cursor; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.util.Optional; +import java.util.function.Function; public final class CursorUtil { @@ -94,4 +96,12 @@ public final class CursorUtil { return row.toString(); } + + public static @Nullable T getAggregateOrDefault(@NonNull Cursor cursor, @Nullable T defaultValue, @NonNull Function cursorColumnFn) { + if (cursor.moveToFirst()) { + return cursorColumnFn.apply(0); + } else { + return defaultValue; + } + } } diff --git a/core-util/src/main/java/org/signal/core/util/SqlUtil.kt b/core-util/src/main/java/org/signal/core/util/SqlUtil.kt index 40ad0c9fe..7efd7f9f2 100644 --- a/core-util/src/main/java/org/signal/core/util/SqlUtil.kt +++ b/core-util/src/main/java/org/signal/core/util/SqlUtil.kt @@ -15,6 +15,9 @@ object SqlUtil { /** The maximum number of arguments (i.e. question marks) allowed in a SQL statement. */ private const val MAX_QUERY_ARGS = 999 + @JvmField + val COUNT = arrayOf("COUNT(*)") + @JvmStatic fun tableExists(db: SupportSQLiteDatabase, table: String): Boolean { db.query("SELECT name FROM sqlite_master WHERE type=? AND name=?", arrayOf("table", table)).use { cursor ->