Remove shortcut as soon as a PIN code is set
This commit is contained in:
parent
3a48e33c81
commit
6691edb59d
|
@ -23,6 +23,7 @@ import androidx.core.content.getSystemService
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
import im.vector.app.core.di.ActiveSessionHolder
|
||||||
import im.vector.app.features.pin.PinCodeStore
|
import im.vector.app.features.pin.PinCodeStore
|
||||||
|
import im.vector.app.features.pin.PinCodeStoreListener
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.disposables.Disposables
|
import io.reactivex.disposables.Disposables
|
||||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||||
|
@ -38,16 +39,22 @@ class ShortcutsHandler @Inject constructor(
|
||||||
private val shortcutCreator: ShortcutCreator,
|
private val shortcutCreator: ShortcutCreator,
|
||||||
private val activeSessionHolder: ActiveSessionHolder,
|
private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val pinCodeStore: PinCodeStore
|
private val pinCodeStore: PinCodeStore
|
||||||
) {
|
) : PinCodeStoreListener {
|
||||||
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
|
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
|
||||||
|
|
||||||
|
// Value will be set correctly if necessary
|
||||||
|
private var hasPinCode = true
|
||||||
|
|
||||||
fun observeRoomsAndBuildShortcuts(): Disposable {
|
fun observeRoomsAndBuildShortcuts(): Disposable {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) {
|
||||||
// No op
|
// No op
|
||||||
return Disposables.empty()
|
return Disposables.empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasPinCode = pinCodeStore.getEncodedPin() != null
|
||||||
|
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty()
|
val session = activeSessionHolder.getSafeActiveSession() ?: return Disposables.empty()
|
||||||
|
pinCodeStore.addListener(this)
|
||||||
return session.getRoomSummariesLive(
|
return session.getRoomSummariesLive(
|
||||||
roomSummaryQueryParams {
|
roomSummaryQueryParams {
|
||||||
memberships = listOf(Membership.JOIN)
|
memberships = listOf(Membership.JOIN)
|
||||||
|
@ -55,6 +62,9 @@ class ShortcutsHandler @Inject constructor(
|
||||||
sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY
|
sortOrder = RoomSortOrder.PRIORITY_AND_ACTIVITY
|
||||||
)
|
)
|
||||||
.asObservable()
|
.asObservable()
|
||||||
|
.doOnDispose {
|
||||||
|
pinCodeStore.removeListener(this)
|
||||||
|
}
|
||||||
.subscribe { rooms ->
|
.subscribe { rooms ->
|
||||||
// Remove dead shortcuts (i.e. deleted rooms)
|
// Remove dead shortcuts (i.e. deleted rooms)
|
||||||
removeDeadShortcut(rooms.map { it.roomId })
|
removeDeadShortcut(rooms.map { it.roomId })
|
||||||
|
@ -81,7 +91,7 @@ class ShortcutsHandler @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createShortcuts(rooms: List<RoomSummary>) {
|
private fun createShortcuts(rooms: List<RoomSummary>) {
|
||||||
if (pinCodeStore.getEncodedPin() != null) {
|
if (hasPinCode) {
|
||||||
// No shortcut in this case (privacy)
|
// No shortcut in this case (privacy)
|
||||||
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
|
ShortcutManagerCompat.removeAllDynamicShortcuts(context)
|
||||||
} else {
|
} 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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
|
@ -56,17 +57,30 @@ interface PinCodeStore {
|
||||||
* Will reset the counters
|
* Will reset the counters
|
||||||
*/
|
*/
|
||||||
fun resetCounters()
|
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) {
|
@Singleton
|
||||||
|
class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences: SharedPreferences) : PinCodeStore {
|
||||||
|
private val listeners = mutableSetOf<PinCodeStoreListener>()
|
||||||
|
|
||||||
|
override suspend fun storeEncodedPin(encodePin: String) {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
putString(ENCODED_PIN_CODE_KEY, encodePin)
|
putString(ENCODED_PIN_CODE_KEY, encodePin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
listeners.forEach { it.onPinSetUpChange(isConfigured = true) }
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun deleteEncodedPin() = withContext(Dispatchers.IO) {
|
override suspend fun deleteEncodedPin() {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
// Also reset the counters
|
// Also reset the counters
|
||||||
resetCounters()
|
resetCounters()
|
||||||
sharedPreferences.edit {
|
sharedPreferences.edit {
|
||||||
|
@ -75,7 +89,8 @@ class SharedPrefPinCodeStore @Inject constructor(private val sharedPreferences:
|
||||||
awaitPinCodeCallback<Boolean> {
|
awaitPinCodeCallback<Boolean> {
|
||||||
PFSecurityManager.getInstance().pinCodeHelper.delete(it)
|
PFSecurityManager.getInstance().pinCodeHelper.delete(it)
|
||||||
}
|
}
|
||||||
return@withContext
|
}
|
||||||
|
listeners.forEach { it.onPinSetUpChange(isConfigured = false) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getEncodedPin(): String? {
|
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 <T> awaitPinCodeCallback(crossinline callback: (PFPinCodeHelperCallback<T>) -> Unit) = suspendCoroutine<PFResult<T>> { cont ->
|
private suspend inline fun <T> awaitPinCodeCallback(crossinline callback: (PFPinCodeHelperCallback<T>) -> Unit) = suspendCoroutine<PFResult<T>> { cont ->
|
||||||
callback(PFPinCodeHelperCallback<T> { result -> cont.resume(result) })
|
callback(PFPinCodeHelperCallback<T> { result -> cont.resume(result) })
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue