From 9b75da5d4d5fc910649bde82c42aa3f6d108e291 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 22 Oct 2021 17:39:06 +0200 Subject: [PATCH 1/8] Clean code --- .../im/vector/app/features/home/ShortcutsHandler.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 7514d455aa..04bbd8f191 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -42,15 +42,16 @@ class ShortcutsHandler @Inject constructor( return Disposables.empty() } - return activeSessionHolder.getSafeActiveSession() - ?.getPagedRoomSummariesLive( + val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty() + return session + .getPagedRoomSummariesLive( roomSummaryQueryParams { memberships = listOf(Membership.JOIN) }, sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY ) - ?.asObservable() - ?.subscribe { rooms -> + .asObservable() + .subscribe { rooms -> // Remove dead shortcuts (i.e. deleted rooms) val roomIds = rooms.map { it.roomId } val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) @@ -66,7 +67,6 @@ class ShortcutsHandler @Inject constructor( ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) } } - ?: Disposables.empty() } fun clearShortcuts() { From 76314b9d87cd2a6951e9f55148873aa7867d548e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 22 Oct 2021 18:01:40 +0200 Subject: [PATCH 2/8] Add `sortOrder: RoomSortOrder` parameter, with no API break --- .../sdk/api/session/room/RoomService.kt | 6 +++-- .../sdk/api/session/space/SpaceService.kt | 7 ++++-- .../session/room/DefaultRoomService.kt | 10 +++++---- .../room/summary/RoomSummaryDataSource.kt | 22 ++++++++++--------- .../session/space/DefaultSpaceService.kt | 11 ++++++---- 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index d80faa729c..e4bd498990 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -94,13 +94,15 @@ interface RoomService { * Get a snapshot list of room summaries. * @return the immutable list of [RoomSummary] */ - fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List + fun getRoomSummaries(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): List /** * Get a live list of room summaries. This list is refreshed as soon as the data changes. * @return the [LiveData] of List[RoomSummary] */ - fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData> + fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.ACTIVITY): LiveData> /** * Get a snapshot list of Breadcrumbs diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt index f40572518f..357c0b941a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.space import android.net.Uri import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult @@ -74,9 +75,11 @@ interface SpaceService { * Get a live list of space summaries. This list is refreshed as soon as the data changes. * @return the [LiveData] of List[SpaceSummary] */ - fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData> + fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData> - fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List + fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): List suspend fun joinSpace(spaceIdOrAlias: String, reason: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index 5b2499c130..7ca64aa66a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -85,12 +85,14 @@ internal class DefaultRoomService @Inject constructor( return roomSummaryDataSource.getRoomSummary(roomIdOrAlias) } - override fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List { - return roomSummaryDataSource.getRoomSummaries(queryParams) + override fun getRoomSummaries(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder): List { + return roomSummaryDataSource.getRoomSummaries(queryParams, sortOrder) } - override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData> { - return roomSummaryDataSource.getRoomSummariesLive(queryParams) + override fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder): LiveData> { + return roomSummaryDataSource.getRoomSummariesLive(queryParams, sortOrder) } override fun getPagedRoomSummariesLive(queryParams: RoomSummaryQueryParams, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt index 0b8c6df806..dd14b32463 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryDataSource.kt @@ -25,7 +25,6 @@ import androidx.paging.PagedList import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.RealmQuery -import io.realm.Sort import io.realm.kotlin.where import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter @@ -80,25 +79,27 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat } } - fun getRoomSummaries(queryParams: RoomSummaryQueryParams): List { + fun getRoomSummaries(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): List { return monarchy.fetchAllMappedSync( - { roomSummariesQuery(it, queryParams) }, + { roomSummariesQuery(it, queryParams).process(sortOrder) }, { roomSummaryMapper.map(it) } ) } - fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams): LiveData> { + fun getRoomSummariesLive(queryParams: RoomSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData> { return monarchy.findAllMappedWithChanges( { - roomSummariesQuery(it, queryParams) - .sort(RoomSummaryEntityFields.LAST_ACTIVITY_TIME, Sort.DESCENDING) + roomSummariesQuery(it, queryParams).process(sortOrder) }, { roomSummaryMapper.map(it) } ) } - fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData> { - return getRoomSummariesLive(queryParams) + fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): LiveData> { + return getRoomSummariesLive(queryParams, sortOrder) } fun getSpaceSummary(roomIdOrAlias: String): RoomSummary? { @@ -122,8 +123,9 @@ internal class RoomSummaryDataSource @Inject constructor(@SessionDatabase privat } } - fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List { - return getRoomSummaries(spaceSummaryQueryParams) + fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder = RoomSortOrder.NONE): List { + return getRoomSummaries(spaceSummaryQueryParams, sortOrder) } fun getRootSpaceSummaries(): List { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt index ac20c79058..ebd5f2578e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent @@ -94,12 +95,14 @@ internal class DefaultSpaceService @Inject constructor( return spaceGetter.get(spaceId) } - override fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams): LiveData> { - return roomSummaryDataSource.getSpaceSummariesLive(queryParams) + override fun getSpaceSummariesLive(queryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder): LiveData> { + return roomSummaryDataSource.getSpaceSummariesLive(queryParams, sortOrder) } - override fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams): List { - return roomSummaryDataSource.getSpaceSummaries(spaceSummaryQueryParams) + override fun getSpaceSummaries(spaceSummaryQueryParams: SpaceSummaryQueryParams, + sortOrder: RoomSortOrder): List { + return roomSummaryDataSource.getSpaceSummaries(spaceSummaryQueryParams, sortOrder) } override fun getRootSpaceSummaries(): List { From f166348a68aa863a2d50f222057328e3fe43b82f Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 22 Oct 2021 18:10:32 +0200 Subject: [PATCH 3/8] Ensure ShortcutsHandler get all the joined rooms #4168 --- .../im/vector/app/features/home/ShortcutsHandler.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 04bbd8f191..89e431cc59 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -43,13 +43,12 @@ class ShortcutsHandler @Inject constructor( } val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty() - return session - .getPagedRoomSummariesLive( - roomSummaryQueryParams { - memberships = listOf(Membership.JOIN) - }, - sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY - ) + return session.getRoomSummariesLive( + roomSummaryQueryParams { + memberships = listOf(Membership.JOIN) + }, + sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY + ) .asObservable() .subscribe { rooms -> // Remove dead shortcuts (i.e. deleted rooms) From 3a81c1006212da896ee9f8f890e2493c4ffccd37 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 27 Oct 2021 15:13:07 +0200 Subject: [PATCH 4/8] Remove (disable) shortcut if a room is left --- .../app/features/home/ShortcutsHandler.kt | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 89e431cc59..d0f805c75a 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -26,8 +26,10 @@ import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposables import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.model.Membership +import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.rx.asObservable +import timber.log.Timber import javax.inject.Inject class ShortcutsHandler @Inject constructor( @@ -52,22 +54,40 @@ class ShortcutsHandler @Inject constructor( .asObservable() .subscribe { rooms -> // Remove dead shortcuts (i.e. deleted rooms) - val roomIds = rooms.map { it.roomId } - val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) - .map { it.id } - .filter { !roomIds.contains(it) } - ShortcutManagerCompat.removeLongLivedShortcuts(context, deadShortcutIds) + removeDeadShortcut(rooms.map { it.roomId }) - val shortcuts = rooms.mapIndexed { index, room -> - shortcutCreator.create(room, index) - } - - shortcuts.forEach { shortcut -> - ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) - } + // Create shortcuts + createShortcuts(rooms) } } + + private fun removeDeadShortcut(roomIds: List) { + val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) + .map { it.id } + .filter { !roomIds.contains(it) } + + if (deadShortcutIds.isNotEmpty()) { + Timber.d("Removing shortcut(s) $deadShortcutIds") + ShortcutManagerCompat.removeLongLivedShortcuts(context, deadShortcutIds) + if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + context.getSystemService()?.disableShortcuts(deadShortcutIds) + } + } + } + } + + private fun createShortcuts(rooms: List) { + val shortcuts = rooms.mapIndexed { index, room -> + shortcutCreator.create(room, index) + } + + shortcuts.forEach { shortcut -> + ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) + } + } + fun clearShortcuts() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) { // No op From 6f577d823281ee7e4edc9ab28df69727cc6e53bf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 27 Oct 2021 15:24:24 +0200 Subject: [PATCH 5/8] Do not show shortcuts if a PIN code is set --- changelog.d/4170.bugfix | 1 + .../app/features/home/ShortcutsHandler.kt | 20 ++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 changelog.d/4170.bugfix diff --git a/changelog.d/4170.bugfix b/changelog.d/4170.bugfix new file mode 100644 index 0000000000..3c1cc4361f --- /dev/null +++ b/changelog.d/4170.bugfix @@ -0,0 +1 @@ +Do not show shortcuts if a PIN code is set \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index d0f805c75a..005ca30845 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -22,6 +22,7 @@ import android.os.Build import androidx.core.content.getSystemService import androidx.core.content.pm.ShortcutManagerCompat import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.features.pin.PinCodeStore import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposables import org.matrix.android.sdk.api.session.room.RoomSortOrder @@ -35,7 +36,8 @@ import javax.inject.Inject class ShortcutsHandler @Inject constructor( private val context: Context, private val shortcutCreator: ShortcutCreator, - private val activeSessionHolder: ActiveSessionHolder + private val activeSessionHolder: ActiveSessionHolder, + private val pinCodeStore: PinCodeStore ) { fun observeRoomsAndBuildShortcuts(): Disposable { @@ -61,7 +63,6 @@ class ShortcutsHandler @Inject constructor( } } - private fun removeDeadShortcut(roomIds: List) { val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) .map { it.id } @@ -79,12 +80,17 @@ class ShortcutsHandler @Inject constructor( } private fun createShortcuts(rooms: List) { - val shortcuts = rooms.mapIndexed { index, room -> - shortcutCreator.create(room, index) - } + if (pinCodeStore.getEncodedPin() != null) { + // No shortcut in this case (privacy) + ShortcutManagerCompat.removeAllDynamicShortcuts(context) + } else { + val shortcuts = rooms.mapIndexed { index, room -> + shortcutCreator.create(room, index) + } - shortcuts.forEach { shortcut -> - ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) + shortcuts.forEach { shortcut -> + ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) + } } } From 3a48e33c812662ef188ee7872b86f134c5c59630 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 27 Oct 2021 15:26:31 +0200 Subject: [PATCH 6/8] Cache immutable value --- .../java/im/vector/app/features/home/ShortcutsHandler.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index 005ca30845..d7e1122246 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -39,6 +39,7 @@ class ShortcutsHandler @Inject constructor( private val activeSessionHolder: ActiveSessionHolder, private val pinCodeStore: PinCodeStore ) { + private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context) fun observeRoomsAndBuildShortcuts(): Disposable { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) { @@ -71,7 +72,7 @@ class ShortcutsHandler @Inject constructor( if (deadShortcutIds.isNotEmpty()) { Timber.d("Removing shortcut(s) $deadShortcutIds") ShortcutManagerCompat.removeLongLivedShortcuts(context, deadShortcutIds) - if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) { + if (isRequestPinShortcutSupported) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { context.getSystemService()?.disableShortcuts(deadShortcutIds) } @@ -107,7 +108,7 @@ class ShortcutsHandler @Inject constructor( ShortcutManagerCompat.removeLongLivedShortcuts(context, shortcuts) // We can only disabled pinned shortcuts with the API, but at least it will prevent the crash - if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) { + if (isRequestPinShortcutSupported) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { context.getSystemService() ?.let { From 6691edb59da9b90e149fe78c601b8e7e47ddb4fa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 27 Oct 2021 16:17:53 +0200 Subject: [PATCH 7/8] Remove shortcut as soon as a PIN code is set --- .../app/features/home/ShortcutsHandler.kt | 24 ++++++++- .../vector/app/features/pin/PinCodeStore.kt | 49 ++++++++++++++----- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index d7e1122246..f27cd30494 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -23,6 +23,7 @@ import androidx.core.content.getSystemService import androidx.core.content.pm.ShortcutManagerCompat import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.pin.PinCodeStore +import im.vector.app.features.pin.PinCodeStoreListener import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposables import org.matrix.android.sdk.api.session.room.RoomSortOrder @@ -38,16 +39,22 @@ class ShortcutsHandler @Inject constructor( private val shortcutCreator: ShortcutCreator, private val activeSessionHolder: ActiveSessionHolder, private val pinCodeStore: PinCodeStore -) { +) : PinCodeStoreListener { private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context) + // Value will be set correctly if necessary + private var hasPinCode = true + fun observeRoomsAndBuildShortcuts(): Disposable { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) { // No op return Disposables.empty() } + hasPinCode = pinCodeStore.getEncodedPin() != null + val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty() + pinCodeStore.addListener(this) return session.getRoomSummariesLive( roomSummaryQueryParams { memberships = listOf(Membership.JOIN) @@ -55,6 +62,9 @@ class ShortcutsHandler @Inject constructor( sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY ) .asObservable() + .doOnDispose { + pinCodeStore.removeListener(this) + } .subscribe { rooms -> // Remove dead shortcuts (i.e. deleted rooms) removeDeadShortcut(rooms.map { it.roomId }) @@ -81,7 +91,7 @@ class ShortcutsHandler @Inject constructor( } private fun createShortcuts(rooms: List) { - if (pinCodeStore.getEncodedPin() != null) { + if (hasPinCode) { // No shortcut in this case (privacy) ShortcutManagerCompat.removeAllDynamicShortcuts(context) } else { @@ -117,4 +127,14 @@ class ShortcutsHandler @Inject constructor( } } } + + override fun onPinSetUpChange(isConfigured: Boolean) { + hasPinCode = isConfigured + if (isConfigured) { + // Remove shortcuts immediately + ShortcutManagerCompat.removeAllDynamicShortcuts(context) + } + // Else shortcut will be created next time any room summary is updated, or + // next time the app is started which is acceptable + } } diff --git a/vector/src/main/java/im/vector/app/features/pin/PinCodeStore.kt b/vector/src/main/java/im/vector/app/features/pin/PinCodeStore.kt index fb7c6897e2..d3632edbca 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinCodeStore.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinCodeStore.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.extensions.orFalse import javax.inject.Inject +import javax.inject.Singleton import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -56,26 +57,40 @@ interface PinCodeStore { * Will reset the counters */ fun resetCounters() + + fun addListener(listener: PinCodeStoreListener) + fun removeListener(listener: PinCodeStoreListener) } -class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: SharedPreferences) : PinCodeStore { +interface PinCodeStoreListener { + fun onPinSetUpChange(isConfigured: Boolean) +} - override suspend fun storeEncodedPin(encodePin: String) = withContext(Dispatchers.IO) { - sharedPreferences.edit { - putString(ENCODED_PIN_CODE_KEY, encodePin) +@Singleton +class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: SharedPreferences) : PinCodeStore { + private val listeners = mutableSetOf() + + override suspend fun storeEncodedPin(encodePin: String) { + withContext(Dispatchers.IO) { + sharedPreferences.edit { + putString(ENCODED_PIN_CODE_KEY, encodePin) + } } + listeners.forEach { it.onPinSetUpChange(isConfigured = true) } } - override suspend fun deleteEncodedPin() = withContext(Dispatchers.IO) { - // Also reset the counters - resetCounters() - sharedPreferences.edit { - remove(ENCODED_PIN_CODE_KEY) + override suspend fun deleteEncodedPin() { + withContext(Dispatchers.IO) { + // Also reset the counters + resetCounters() + sharedPreferences.edit { + remove(ENCODED_PIN_CODE_KEY) + } + awaitPinCodeCallback { + PFSecurityManager.getInstance().pinCodeHelper.delete(it) + } } - awaitPinCodeCallback { - PFSecurityManager.getInstance().pinCodeHelper.delete(it) - } - return@withContext + listeners.forEach { it.onPinSetUpChange(isConfigured = false) } } override fun getEncodedPin(): String? { @@ -124,6 +139,14 @@ class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: } } + override fun addListener(listener: PinCodeStoreListener) { + listeners.add(listener) + } + + override fun removeListener(listener: PinCodeStoreListener) { + listeners.remove(listener) + } + private suspend inline fun awaitPinCodeCallback(crossinline callback: (PFPinCodeHelperCallback) -> Unit) = suspendCoroutine> { cont -> callback(PFPinCodeHelperCallback { result -> cont.resume(result) }) } From 34e8cf84dc7427fe18e22a9d9ab211e2c7bb7b41 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 28 Oct 2021 09:41:27 +0200 Subject: [PATCH 8/8] Improve Rx sequence regarding listener --- .../java/im/vector/app/features/home/ShortcutsHandler.kt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt index f27cd30494..612e2dcf87 100644 --- a/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt +++ b/vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt @@ -54,7 +54,6 @@ class ShortcutsHandler @Inject constructor( hasPinCode = pinCodeStore.getEncodedPin() != null val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty() - pinCodeStore.addListener(this) return session.getRoomSummariesLive( roomSummaryQueryParams { memberships = listOf(Membership.JOIN) @@ -62,9 +61,8 @@ class ShortcutsHandler @Inject constructor( sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY ) .asObservable() - .doOnDispose { - pinCodeStore.removeListener(this) - } + .doOnSubscribe { pinCodeStore.addListener(this) } + .doFinally { pinCodeStore.removeListener(this) } .subscribe { rooms -> // Remove dead shortcuts (i.e. deleted rooms) removeDeadShortcut(rooms.map { it.roomId })