@@ -22,51 +22,85 @@ import android.os.Build
22
22
import androidx.core.content.getSystemService
23
23
import androidx.core.content.pm.ShortcutManagerCompat
24
24
import im.vector.app.core.di.ActiveSessionHolder
25
+ import im.vector.app.features.pin.PinCodeStore
26
+ import im.vector.app.features.pin.PinCodeStoreListener
25
27
import io.reactivex.disposables.Disposable
26
28
import io.reactivex.disposables.Disposables
27
29
import org.matrix.android.sdk.api.session.room.RoomSortOrder
28
30
import org.matrix.android.sdk.api.session.room.model.Membership
31
+ import org.matrix.android.sdk.api.session.room.model.RoomSummary
29
32
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
30
33
import org.matrix.android.sdk.rx.asObservable
34
+ import timber.log.Timber
31
35
import javax.inject.Inject
32
36
33
37
class ShortcutsHandler @Inject constructor(
34
38
private val context : Context ,
35
39
private val shortcutCreator : ShortcutCreator ,
36
- private val activeSessionHolder : ActiveSessionHolder
37
- ) {
40
+ private val activeSessionHolder : ActiveSessionHolder ,
41
+ private val pinCodeStore : PinCodeStore
42
+ ) : PinCodeStoreListener {
43
+ private val isRequestPinShortcutSupported = ShortcutManagerCompat .isRequestPinShortcutSupported(context)
44
+
45
+ // Value will be set correctly if necessary
46
+ private var hasPinCode = true
38
47
39
48
fun observeRoomsAndBuildShortcuts (): Disposable {
40
49
if (Build .VERSION .SDK_INT < Build .VERSION_CODES .N_MR1 ) {
41
50
// No op
42
51
return Disposables .empty()
43
52
}
44
53
45
- return activeSessionHolder.getSafeActiveSession()
46
- ?.getPagedRoomSummariesLive(
47
- roomSummaryQueryParams {
48
- memberships = listOf (Membership .JOIN )
49
- },
50
- sortOrder = RoomSortOrder .PRIORITY_AND_ACTIVITY
51
- )
52
- ?.asObservable()
53
- ?.subscribe { rooms ->
54
+ hasPinCode = pinCodeStore.getEncodedPin() != null
55
+
56
+ val session = activeSessionHolder.getSafeActiveSession() ? : return Disposables .empty()
57
+ return session.getRoomSummariesLive(
58
+ roomSummaryQueryParams {
59
+ memberships = listOf (Membership .JOIN )
60
+ },
61
+ sortOrder = RoomSortOrder .PRIORITY_AND_ACTIVITY
62
+ )
63
+ .asObservable()
64
+ .doOnSubscribe { pinCodeStore.addListener(this ) }
65
+ .doFinally { pinCodeStore.removeListener(this ) }
66
+ .subscribe { rooms ->
54
67
// Remove dead shortcuts (i.e. deleted rooms)
55
- val roomIds = rooms.map { it.roomId }
56
- val deadShortcutIds = ShortcutManagerCompat .getShortcuts(context, ShortcutManagerCompat .FLAG_MATCH_DYNAMIC )
57
- .map { it.id }
58
- .filter { ! roomIds.contains(it) }
59
- ShortcutManagerCompat .removeLongLivedShortcuts(context, deadShortcutIds)
60
-
61
- val shortcuts = rooms.mapIndexed { index, room ->
62
- shortcutCreator.create(room, index)
63
- }
64
-
65
- shortcuts.forEach { shortcut ->
66
- ShortcutManagerCompat .pushDynamicShortcut(context, shortcut)
67
- }
68
+ removeDeadShortcut(rooms.map { it.roomId })
69
+
70
+ // Create shortcuts
71
+ createShortcuts(rooms)
68
72
}
69
- ? : Disposables .empty()
73
+ }
74
+
75
+ private fun removeDeadShortcut (roomIds : List <String >) {
76
+ val deadShortcutIds = ShortcutManagerCompat .getShortcuts(context, ShortcutManagerCompat .FLAG_MATCH_DYNAMIC )
77
+ .map { it.id }
78
+ .filter { ! roomIds.contains(it) }
79
+
80
+ if (deadShortcutIds.isNotEmpty()) {
81
+ Timber .d(" Removing shortcut(s) $deadShortcutIds " )
82
+ ShortcutManagerCompat .removeLongLivedShortcuts(context, deadShortcutIds)
83
+ if (isRequestPinShortcutSupported) {
84
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N_MR1 ) {
85
+ context.getSystemService<ShortcutManager >()?.disableShortcuts(deadShortcutIds)
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ private fun createShortcuts (rooms : List <RoomSummary >) {
92
+ if (hasPinCode) {
93
+ // No shortcut in this case (privacy)
94
+ ShortcutManagerCompat .removeAllDynamicShortcuts(context)
95
+ } else {
96
+ val shortcuts = rooms.mapIndexed { index, room ->
97
+ shortcutCreator.create(room, index)
98
+ }
99
+
100
+ shortcuts.forEach { shortcut ->
101
+ ShortcutManagerCompat .pushDynamicShortcut(context, shortcut)
102
+ }
103
+ }
70
104
}
71
105
72
106
fun clearShortcuts () {
@@ -82,7 +116,7 @@ class ShortcutsHandler @Inject constructor(
82
116
ShortcutManagerCompat .removeLongLivedShortcuts(context, shortcuts)
83
117
84
118
// We can only disabled pinned shortcuts with the API, but at least it will prevent the crash
85
- if (ShortcutManagerCompat . isRequestPinShortcutSupported(context) ) {
119
+ if (isRequestPinShortcutSupported) {
86
120
if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N_MR1 ) {
87
121
context.getSystemService<ShortcutManager >()
88
122
?.let {
@@ -91,4 +125,14 @@ class ShortcutsHandler @Inject constructor(
91
125
}
92
126
}
93
127
}
128
+
129
+ override fun onPinSetUpChange (isConfigured : Boolean ) {
130
+ hasPinCode = isConfigured
131
+ if (isConfigured) {
132
+ // Remove shortcuts immediately
133
+ ShortcutManagerCompat .removeAllDynamicShortcuts(context)
134
+ }
135
+ // Else shortcut will be created next time any room summary is updated, or
136
+ // next time the app is started which is acceptable
137
+ }
94
138
}
0 commit comments