Skip to content

Commit 6691edb

Browse files
committed
Remove shortcut as soon as a PIN code is set
1 parent 3a48e33 commit 6691edb

File tree

2 files changed

+57
-14
lines changed

2 files changed

+57
-14
lines changed

vector/src/main/java/im/vector/app/features/home/ShortcutsHandler.kt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import androidx.core.content.getSystemService
2323
import androidx.core.content.pm.ShortcutManagerCompat
2424
import im.vector.app.core.di.ActiveSessionHolder
2525
import im.vector.app.features.pin.PinCodeStore
26+
import im.vector.app.features.pin.PinCodeStoreListener
2627
import io.reactivex.disposables.Disposable
2728
import io.reactivex.disposables.Disposables
2829
import org.matrix.android.sdk.api.session.room.RoomSortOrder
@@ -38,23 +39,32 @@ class ShortcutsHandler @Inject constructor(
3839
private val shortcutCreator: ShortcutCreator,
3940
private val activeSessionHolder: ActiveSessionHolder,
4041
private val pinCodeStore: PinCodeStore
41-
) {
42+
) : PinCodeStoreListener {
4243
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
4344

45+
// Value will be set correctly if necessary
46+
private var hasPinCode = true
47+
4448
fun observeRoomsAndBuildShortcuts(): Disposable {
4549
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
4650
// No op
4751
return Disposables.empty()
4852
}
4953

54+
hasPinCode = pinCodeStore.getEncodedPin() != null
55+
5056
val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty()
57+
pinCodeStore.addListener(this)
5158
return session.getRoomSummariesLive(
5259
roomSummaryQueryParams {
5360
memberships = listOf(Membership.JOIN)
5461
},
5562
sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY
5663
)
5764
.asObservable()
65+
.doOnDispose {
66+
pinCodeStore.removeListener(this)
67+
}
5868
.subscribe { rooms ->
5969
// Remove dead shortcuts (i.e. deleted rooms)
6070
removeDeadShortcut(rooms.map { it.roomId })
@@ -81,7 +91,7 @@ class ShortcutsHandler @Inject constructor(
8191
}
8292

8393
private fun createShortcuts(rooms: List<RoomSummary>) {
84-
if (pinCodeStore.getEncodedPin() != null) {
94+
if (hasPinCode) {
8595
// No shortcut in this case (privacy)
8696
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
8797
} else {
@@ -117,4 +127,14 @@ class ShortcutsHandler @Inject constructor(
117127
}
118128
}
119129
}
130+
131+
override fun onPinSetUpChange(isConfigured: Boolean) {
132+
hasPinCode = isConfigured
133+
if (isConfigured) {
134+
// Remove shortcuts immediately
135+
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
136+
}
137+
// Else shortcut will be created next time any room summary is updated, or
138+
// next time the app is started which is acceptable
139+
}
120140
}

vector/src/main/java/im/vector/app/features/pin/PinCodeStore.kt

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import kotlinx.coroutines.Dispatchers
2525
import kotlinx.coroutines.withContext
2626
import org.matrix.android.sdk.api.extensions.orFalse
2727
import javax.inject.Inject
28+
import javax.inject.Singleton
2829
import kotlin.coroutines.resume
2930
import kotlin.coroutines.suspendCoroutine
3031

@@ -56,26 +57,40 @@ interface PinCodeStore {
5657
* Will reset the counters
5758
*/
5859
fun resetCounters()
60+
61+
fun addListener(listener: PinCodeStoreListener)
62+
fun removeListener(listener: PinCodeStoreListener)
63+
}
64+
65+
interface PinCodeStoreListener {
66+
fun onPinSetUpChange(isConfigured: Boolean)
5967
}
6068

69+
@Singleton
6170
class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: SharedPreferences) : PinCodeStore {
71+
private val listeners = mutableSetOf<PinCodeStoreListener>()
6272

63-
override suspend fun storeEncodedPin(encodePin: String) = withContext(Dispatchers.IO) {
64-
sharedPreferences.edit {
65-
putString(ENCODED_PIN_CODE_KEY, encodePin)
73+
override suspend fun storeEncodedPin(encodePin: String) {
74+
withContext(Dispatchers.IO) {
75+
sharedPreferences.edit {
76+
putString(ENCODED_PIN_CODE_KEY, encodePin)
77+
}
6678
}
79+
listeners.forEach { it.onPinSetUpChange(isConfigured = true) }
6780
}
6881

69-
override suspend fun deleteEncodedPin() = withContext(Dispatchers.IO) {
70-
// Also reset the counters
71-
resetCounters()
72-
sharedPreferences.edit {
73-
remove(ENCODED_PIN_CODE_KEY)
82+
override suspend fun deleteEncodedPin() {
83+
withContext(Dispatchers.IO) {
84+
// Also reset the counters
85+
resetCounters()
86+
sharedPreferences.edit {
87+
remove(ENCODED_PIN_CODE_KEY)
88+
}
89+
awaitPinCodeCallback<Boolean> {
90+
PFSecurityManager.getInstance().pinCodeHelper.delete(it)
91+
}
7492
}
75-
awaitPinCodeCallback<Boolean> {
76-
PFSecurityManager.getInstance().pinCodeHelper.delete(it)
77-
}
78-
return@withContext
93+
listeners.forEach { it.onPinSetUpChange(isConfigured = false) }
7994
}
8095

8196
override fun getEncodedPin(): String? {
@@ -124,6 +139,14 @@ class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences:
124139
}
125140
}
126141

142+
override fun addListener(listener: PinCodeStoreListener) {
143+
listeners.add(listener)
144+
}
145+
146+
override fun removeListener(listener: PinCodeStoreListener) {
147+
listeners.remove(listener)
148+
}
149+
127150
private suspend inline fun <T> awaitPinCodeCallback(crossinline callback: (PFPinCodeHelperCallback<T>) -> Unit) = suspendCoroutine<PFResult<T>> { cont ->
128151
callback(PFPinCodeHelperCallback<T> { result -> cont.resume(result) })
129152
}

0 commit comments

Comments
 (0)