Merge pull request #6677 from vector-im/feature/bma/fix_room_shortcut

Shortcuts must first start MainActivity to ensure the session is restored.
This commit is contained in:
Benoit Marty 2022-07-28 20:39:41 +02:00 committed by GitHub
commit 24e78fef74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 21 deletions

View File

@ -86,6 +86,8 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
private const val EXTRA_ARGS = "EXTRA_ARGS" private const val EXTRA_ARGS = "EXTRA_ARGS"
private const val EXTRA_NEXT_INTENT = "EXTRA_NEXT_INTENT" private const val EXTRA_NEXT_INTENT = "EXTRA_NEXT_INTENT"
private const val EXTRA_INIT_SESSION = "EXTRA_INIT_SESSION" private const val EXTRA_INIT_SESSION = "EXTRA_INIT_SESSION"
private const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
private const val ACTION_ROOM_DETAILS_FROM_SHORTCUT = "ROOM_DETAILS_FROM_SHORTCUT"
// Special action to clear cache and/or clear credentials // Special action to clear cache and/or clear credentials
fun restartApp(activity: Activity, args: MainActivityArgs) { fun restartApp(activity: Activity, args: MainActivityArgs) {
@ -107,6 +109,14 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
intent.putExtra(EXTRA_NEXT_INTENT, nextIntent) intent.putExtra(EXTRA_NEXT_INTENT, nextIntent)
return intent return intent
} }
// Shortcuts can't have intents with parcelables
fun shortcutIntent(context: Context, roomId: String): Intent {
return Intent(context, MainActivity::class.java).apply {
action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
putExtra(EXTRA_ROOM_ID, roomId)
}
}
} }
private val startAppViewModel: StartAppViewModel by viewModel() private val startAppViewModel: StartAppViewModel by viewModel()
@ -131,6 +141,8 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
shortcutsHandler.updateShortcutsWithPreviousIntent()
startAppViewModel.onEach { startAppViewModel.onEach {
renderState(it) renderState(it)
} }
@ -171,6 +183,13 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
} else if (intent.hasExtra(EXTRA_INIT_SESSION)) { } else if (intent.hasExtra(EXTRA_INIT_SESSION)) {
setResult(RESULT_OK) setResult(RESULT_OK)
finish() finish()
} else if (intent.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) {
val roomId = intent.getStringExtra(EXTRA_ROOM_ID)
if (roomId?.isNotEmpty() == true) {
// TODO Add a trigger Shortcut to the analytics.
navigator.openRoom(this, roomId)
}
finish()
} else { } else {
args = parseArgs() args = parseArgs()
if (args.clearCredentials || args.isUserLoggedOut || args.clearCache) { if (args.clearCredentials || args.isUserLoggedOut || args.clearCache) {

View File

@ -27,7 +27,7 @@ import androidx.core.graphics.drawable.IconCompat
import im.vector.app.BuildConfig import im.vector.app.BuildConfig
import im.vector.app.core.glide.GlideApp import im.vector.app.core.glide.GlideApp
import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.MainActivity
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toMatrixItem
import javax.inject.Inject import javax.inject.Inject
@ -58,7 +58,7 @@ class ShortcutCreator @Inject constructor(
@WorkerThread @WorkerThread
fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat { fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat {
val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId) val intent = MainActivity.shortcutIntent(context, roomSummary.roomId)
val bitmap = try { val bitmap = try {
val glideRequests = GlideApp.with(context) val glideRequests = GlideApp.with(context)
val matrixItem = roomSummary.toMatrixItem() val matrixItem = roomSummary.toMatrixItem()

View File

@ -16,15 +16,22 @@
package im.vector.app.features.home package im.vector.app.features.home
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.content.SharedPreferences
import android.content.pm.ShortcutManager import android.content.pm.ShortcutManager
import android.os.Build import android.os.Build
import androidx.core.content.edit
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.content.pm.ShortcutManagerCompat
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.di.DefaultPreferences
import im.vector.app.core.dispatchers.CoroutineDispatchers import im.vector.app.core.dispatchers.CoroutineDispatchers
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.features.MainActivity
import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.pin.PinCodeStore import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.PinCodeStoreListener import im.vector.app.features.pin.PinCodeStoreListener
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -35,6 +42,7 @@ import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.room.RoomSortOrder 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.Membership
import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary
@ -50,7 +58,9 @@ class ShortcutsHandler @Inject constructor(
private val appDispatchers: CoroutineDispatchers, private val appDispatchers: CoroutineDispatchers,
private val shortcutCreator: ShortcutCreator, private val shortcutCreator: ShortcutCreator,
private val activeSessionHolder: ActiveSessionHolder, private val activeSessionHolder: ActiveSessionHolder,
private val pinCodeStore: PinCodeStore private val pinCodeStore: PinCodeStore,
@DefaultPreferences
private val sharedPreferences: SharedPreferences,
) : PinCodeStoreListener { ) : PinCodeStoreListener {
private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context) private val isRequestPinShortcutSupported = ShortcutManagerCompat.isRequestPinShortcutSupported(context)
@ -87,6 +97,27 @@ class ShortcutsHandler @Inject constructor(
.launchIn(coroutineScope) .launchIn(coroutineScope)
} }
@SuppressLint("RestrictedApi")
fun updateShortcutsWithPreviousIntent() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return
// Check if it's been already done
if (sharedPreferences.getBoolean(SHARED_PREF_KEY, false)) return
ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_PINNED)
.filter { it.intent.component?.className == RoomDetailActivity::class.qualifiedName }
.mapNotNull {
it.intent.getStringExtra("EXTRA_ROOM_ID")?.let { roomId ->
ShortcutInfoCompat.Builder(context, it.toShortcutInfo())
.setIntent(MainActivity.shortcutIntent(context, roomId))
.build()
}
}
.takeIf { it.isNotEmpty() }
?.also { Timber.d("Update ${it.size} shortcut(s)") }
?.let { tryOrNull("Error") { ShortcutManagerCompat.updateShortcuts(context, it) } }
?.also { Timber.d("Update shortcuts with success: $it") }
sharedPreferences.edit { putBoolean(SHARED_PREF_KEY, true) }
}
private fun removeDeadShortcuts(roomIds: List<String>) { private fun removeDeadShortcuts(roomIds: List<String>) {
val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC) val deadShortcutIds = ShortcutManagerCompat.getShortcuts(context, ShortcutManagerCompat.FLAG_MATCH_DYNAMIC)
.map { it.id } .map { it.id }
@ -163,4 +194,8 @@ class ShortcutsHandler @Inject constructor(
// Else shortcut will be created next time any room summary is updated, or // Else shortcut will be created next time any room summary is updated, or
// next time the app is started which is acceptable // next time the app is started which is acceptable
} }
companion object {
const val SHARED_PREF_KEY = "ROOM_DETAIL_ACTIVITY_SHORTCUT_UPDATED"
}
} }

View File

@ -99,12 +99,7 @@ class RoomDetailActivity :
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false) supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
waitingView = views.waitingView.waitingView waitingView = views.waitingView.waitingView
val timelineArgs: TimelineArgs? = if (intent?.action == ACTION_ROOM_DETAILS_FROM_SHORTCUT) { val timelineArgs: TimelineArgs = intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS) ?: return
TimelineArgs(roomId = intent?.extras?.getString(EXTRA_ROOM_ID)!!)
} else {
intent?.extras?.getParcelable(EXTRA_ROOM_DETAIL_ARGS)
}
if (timelineArgs == null) return
intent.putExtra(Mavericks.KEY_ARG, timelineArgs) intent.putExtra(Mavericks.KEY_ARG, timelineArgs)
currentRoomId = timelineArgs.roomId currentRoomId = timelineArgs.roomId
@ -187,10 +182,7 @@ class RoomDetailActivity :
} }
companion object { companion object {
const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS" const val EXTRA_ROOM_DETAIL_ARGS = "EXTRA_ROOM_DETAIL_ARGS"
const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
const val ACTION_ROOM_DETAILS_FROM_SHORTCUT = "ROOM_DETAILS_FROM_SHORTCUT"
fun newIntent(context: Context, timelineArgs: TimelineArgs, firstStartMainActivity: Boolean): Intent { fun newIntent(context: Context, timelineArgs: TimelineArgs, firstStartMainActivity: Boolean): Intent {
val intent = Intent(context, RoomDetailActivity::class.java).apply { val intent = Intent(context, RoomDetailActivity::class.java).apply {
@ -202,14 +194,6 @@ class RoomDetailActivity :
intent intent
} }
} }
// Shortcuts can't have intents with parcelables
fun shortcutIntent(context: Context, roomId: String): Intent {
return Intent(context, RoomDetailActivity::class.java).apply {
action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
putExtra(EXTRA_ROOM_ID, roomId)
}
}
} }
override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) { override fun mxToBottomSheetNavigateToRoom(roomId: String, trigger: ViewRoom.Trigger?) {

View File

@ -28,6 +28,7 @@ import im.vector.app.R
import im.vector.app.core.di.DefaultSharedPreferences import im.vector.app.core.di.DefaultSharedPreferences
import im.vector.app.core.time.Clock import im.vector.app.core.time.Clock
import im.vector.app.features.disclaimer.SHARED_PREF_KEY import im.vector.app.features.disclaimer.SHARED_PREF_KEY
import im.vector.app.features.home.ShortcutsHandler
import im.vector.app.features.homeserver.ServerUrlsRepository import im.vector.app.features.homeserver.ServerUrlsRepository
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
@ -268,7 +269,9 @@ class VectorPreferences @Inject constructor(
SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY, SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY,
SETTINGS_USE_RAGE_SHAKE_KEY, SETTINGS_USE_RAGE_SHAKE_KEY,
SETTINGS_SECURITY_USE_FLAG_SECURE SETTINGS_SECURITY_USE_FLAG_SECURE,
ShortcutsHandler.SHARED_PREF_KEY,
) )
} }