Display push counter on debug mode

This commit is contained in:
Benoit Marty 2021-09-20 16:54:39 +02:00 committed by Benoit Marty
parent c163d2e271
commit 93506d18fa
13 changed files with 140 additions and 12 deletions

View file

@ -55,6 +55,8 @@ ext.libs = [
'lifecycleExtensions' : "androidx.lifecycle:lifecycle-extensions:$lifecycle", 'lifecycleExtensions' : "androidx.lifecycle:lifecycle-extensions:$lifecycle",
'lifecycleJava8' : "androidx.lifecycle:lifecycle-common-java8:$lifecycle", 'lifecycleJava8' : "androidx.lifecycle:lifecycle-common-java8:$lifecycle",
'lifecycleLivedata' : "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1", 'lifecycleLivedata' : "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1",
'datastore' : "androidx.datastore:datastore:1.0.0",
'datastorepreferences' : "androidx.datastore:datastore-preferences:1.0.0",
'pagingRuntimeKtx' : "androidx.paging:paging-runtime-ktx:2.1.2", 'pagingRuntimeKtx' : "androidx.paging:paging-runtime-ktx:2.1.2",
'coreTesting' : "androidx.arch.core:core-testing:2.1.0", 'coreTesting' : "androidx.arch.core:core-testing:2.1.0",
'testCore' : "androidx.test:core:$androidxTest", 'testCore' : "androidx.test:core:$androidxTest",

View file

@ -345,6 +345,9 @@ dependencies {
implementation libs.androidx.lifecycleExtensions implementation libs.androidx.lifecycleExtensions
implementation libs.androidx.lifecycleLivedata implementation libs.androidx.lifecycleLivedata
implementation libs.androidx.datastore
implementation libs.androidx.datastorepreferences
// Log // Log
implementation libs.jakewharton.timber implementation libs.jakewharton.timber
@ -406,7 +409,7 @@ dependencies {
// To convert voice message on old platforms // To convert voice message on old platforms
implementation 'com.arthenica:ffmpeg-kit-audio:4.4.LTS' implementation 'com.arthenica:ffmpeg-kit-audio:4.4.LTS'
//Alerter // Alerter
implementation 'com.tapadoo.android:alerter:7.0.1' implementation 'com.tapadoo.android:alerter:7.0.1'
implementation 'com.otaliastudios:autocomplete:1.1.0' implementation 'com.otaliastudios:autocomplete:1.1.0'

View file

@ -39,11 +39,13 @@ import im.vector.app.features.notifications.NotifiableMessageEvent
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.notifications.SimpleNotifiableEvent import im.vector.app.features.notifications.SimpleNotifiableEvent
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.push.fcm.FcmHelper import im.vector.app.push.fcm.FcmHelper
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.pushrules.Action import org.matrix.android.sdk.api.pushrules.Action
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
@ -60,6 +62,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
private lateinit var pusherManager: PushersManager private lateinit var pusherManager: PushersManager
private lateinit var activeSessionHolder: ActiveSessionHolder private lateinit var activeSessionHolder: ActiveSessionHolder
private lateinit var vectorPreferences: VectorPreferences private lateinit var vectorPreferences: VectorPreferences
private lateinit var vectorDataStore: VectorDataStore
private lateinit var wifiDetector: WifiDetector private lateinit var wifiDetector: WifiDetector
private val coroutineScope = CoroutineScope(SupervisorJob()) private val coroutineScope = CoroutineScope(SupervisorJob())
@ -77,6 +80,7 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
pusherManager = pusherManager() pusherManager = pusherManager()
activeSessionHolder = activeSessionHolder() activeSessionHolder = activeSessionHolder()
vectorPreferences = vectorPreferences() vectorPreferences = vectorPreferences()
vectorDataStore = vectorDataStore()
wifiDetector = wifiDetector() wifiDetector = wifiDetector()
} }
} }
@ -92,6 +96,10 @@ class VectorFirebaseMessagingService : FirebaseMessagingService() {
} }
Timber.d("## onMessageReceived() from FCM with priority %s", message.priority) Timber.d("## onMessageReceived() from FCM with priority %s", message.priority)
runBlocking {
vectorDataStore.incrementPushCounter()
}
// Diagnostic Push // Diagnostic Push
if (message.data["event_id"] == PushersManager.TEST_EVENT_ID) { if (message.data["event_id"] == PushersManager.TEST_EVENT_ID) {
val intent = Intent(NotificationUtils.PUSH_ACTION) val intent = Intent(NotificationUtils.PUSH_ACTION)

View file

@ -58,6 +58,7 @@ import im.vector.app.features.rageshake.VectorFileLogger
import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler import im.vector.app.features.rageshake.VectorUncaughtExceptionHandler
import im.vector.app.features.reactions.data.EmojiDataSource import im.vector.app.features.reactions.data.EmojiDataSource
import im.vector.app.features.session.SessionListener import im.vector.app.features.session.SessionListener
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.ui.UiStateRepository import im.vector.app.features.ui.UiStateRepository
import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.Matrix
@ -145,6 +146,8 @@ interface VectorComponent {
fun vectorPreferences(): VectorPreferences fun vectorPreferences(): VectorPreferences
fun vectorDataStore(): VectorDataStore
fun wifiDetector(): WifiDetector fun wifiDetector(): WifiDetector
fun vectorFileLogger(): VectorFileLogger fun vectorFileLogger(): VectorFileLogger

View file

@ -440,7 +440,11 @@ class HomeDetailFragment @Inject constructor(
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople)
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms)
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup) views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
views.syncStateView.render(it.syncState, it.incrementalSyncStatus, vectorPreferences.developerShowDebugInfo()) views.syncStateView.render(
it.syncState,
it.incrementalSyncStatus,
it.pushCounter,
vectorPreferences.developerShowDebugInfo())
hasUnreadRooms = it.hasUnreadMessages hasUnreadRooms = it.hasUnreadMessages
} }

View file

@ -33,9 +33,11 @@ import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.createdirect.DirectRoomHelper import im.vector.app.features.createdirect.DirectRoomHelper
import im.vector.app.features.invite.AutoAcceptInvites import im.vector.app.features.invite.AutoAcceptInvites
import im.vector.app.features.invite.showInvites import im.vector.app.features.invite.showInvites
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.ui.UiStateRepository import im.vector.app.features.ui.UiStateRepository
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.ActiveSpaceFilter
import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.query.RoomCategoryFilter
@ -57,6 +59,7 @@ import java.util.concurrent.TimeUnit
class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState, class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: HomeDetailViewState,
private val session: Session, private val session: Session,
private val uiStateRepository: UiStateRepository, private val uiStateRepository: UiStateRepository,
private val vectorDataStore: VectorDataStore,
private val callManager: WebRtcCallManager, private val callManager: WebRtcCallManager,
private val directRoomHelper: DirectRoomHelper, private val directRoomHelper: DirectRoomHelper,
private val appStateHandler: AppStateHandler, private val appStateHandler: AppStateHandler,
@ -90,6 +93,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
observeRoomGroupingMethod() observeRoomGroupingMethod()
observeRoomSummaries() observeRoomSummaries()
updateShowDialPadTab() updateShowDialPadTab()
observeDataStore()
callManager.addProtocolsCheckerListener(this) callManager.addProtocolsCheckerListener(this)
session.rx().liveUser(session.myUserId).execute { session.rx().liveUser(session.myUserId).execute {
copy( copy(
@ -98,6 +102,18 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
} }
} }
private fun observeDataStore() {
viewModelScope.launch {
vectorDataStore.pushCounterFlow.collect { nbOfPush ->
setState {
copy(
pushCounter = nbOfPush
)
}
}
}
}
override fun handle(action: HomeDetailAction) { override fun handle(action: HomeDetailAction) {
when (action) { when (action) {
is HomeDetailAction.SwitchTab -> handleSwitchTab(action) is HomeDetailAction.SwitchTab -> handleSwitchTab(action)

View file

@ -41,6 +41,7 @@ data class HomeDetailViewState(
val hasUnreadMessages: Boolean = false, val hasUnreadMessages: Boolean = false,
val syncState: SyncState = SyncState.Idle, val syncState: SyncState = SyncState.Idle,
val incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus = InitialSyncProgressService.Status.IncrementalSyncIdle, val incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus = InitialSyncProgressService.Status.IncrementalSyncIdle,
val pushCounter: Int = 0,
val showDialPadTab: Boolean = false val showDialPadTab: Boolean = false
) : MvRxState ) : MvRxState

View file

@ -389,9 +389,15 @@ class RoomDetailFragment @Inject constructor(
roomDetailViewModel.selectSubscribe( roomDetailViewModel.selectSubscribe(
RoomDetailViewState::syncState, RoomDetailViewState::syncState,
RoomDetailViewState::incrementalSyncStatus RoomDetailViewState::incrementalSyncStatus,
) { syncState, incrementalSyncStatus -> RoomDetailViewState::pushCounter
views.syncStateView.render(syncState, incrementalSyncStatus, vectorPreferences.developerShowDebugInfo()) ) { syncState, incrementalSyncStatus, pushCounter ->
views.syncStateView.render(
syncState,
incrementalSyncStatus,
pushCounter,
vectorPreferences.developerShowDebugInfo()
)
} }
roomDetailViewModel.observeViewEvents { roomDetailViewModel.observeViewEvents {

View file

@ -57,12 +57,14 @@ import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
import im.vector.app.features.home.room.typing.TypingHelper import im.vector.app.features.home.room.typing.TypingHelper
import im.vector.app.features.powerlevel.PowerLevelsObservableFactory import im.vector.app.features.powerlevel.PowerLevelsObservableFactory
import im.vector.app.features.session.coroutineScope import im.vector.app.features.session.coroutineScope
import im.vector.app.features.settings.VectorDataStore
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.voice.VoicePlayerHelper import im.vector.app.features.voice.VoicePlayerHelper
import io.reactivex.Observable import io.reactivex.Observable
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.commonmark.parser.Parser import org.commonmark.parser.Parser
@ -113,6 +115,7 @@ import java.util.concurrent.atomic.AtomicBoolean
class RoomDetailViewModel @AssistedInject constructor( class RoomDetailViewModel @AssistedInject constructor(
@Assisted private val initialState: RoomDetailViewState, @Assisted private val initialState: RoomDetailViewState,
private val vectorPreferences: VectorPreferences, private val vectorPreferences: VectorPreferences,
private val vectorDataStore: VectorDataStore,
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
private val rainbowGenerator: RainbowGenerator, private val rainbowGenerator: RainbowGenerator,
private val session: Session, private val session: Session,
@ -176,6 +179,7 @@ class RoomDetailViewModel @AssistedInject constructor(
observeSummaryState() observeSummaryState()
getUnreadState() getUnreadState()
observeSyncState() observeSyncState()
observeDataStore()
observeEventDisplayedActions() observeEventDisplayedActions()
loadDraftIfAny() loadDraftIfAny()
observeUnreadState() observeUnreadState()
@ -200,6 +204,18 @@ class RoomDetailViewModel @AssistedInject constructor(
} }
} }
private fun observeDataStore() {
viewModelScope.launch {
vectorDataStore.pushCounterFlow.collect { nbOfPush ->
setState {
copy(
pushCounter = nbOfPush
)
}
}
}
}
private fun prepareForEncryption() { private fun prepareForEncryption() {
// check if there is not already a call made, or if there has been an error // check if there is not already a call made, or if there has been an error
if (prepareToEncrypt.shouldLoad) { if (prepareToEncrypt.shouldLoad) {

View file

@ -79,6 +79,7 @@ data class RoomDetailViewState(
val joinUpgradedRoomAsync: Async<String> = Uninitialized, val joinUpgradedRoomAsync: Async<String> = Uninitialized,
val syncState: SyncState = SyncState.Idle, val syncState: SyncState = SyncState.Idle,
val incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus = InitialSyncProgressService.Status.IncrementalSyncIdle, val incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus = InitialSyncProgressService.Status.IncrementalSyncIdle,
val pushCounter: Int = 0,
val highlightedEventId: String? = null, val highlightedEventId: String? = null,
val unreadState: UnreadState = UnreadState.Unknown, val unreadState: UnreadState = UnreadState.Unknown,
val canShowJumpToReadMarker: Boolean = true, val canShowJumpToReadMarker: Boolean = true,

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2021 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.features.settings
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.intPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "vector_settings")
class VectorDataStore @Inject constructor(
private val context: Context
) {
private val pushCounter = intPreferencesKey("push_counter")
val pushCounterFlow: Flow<Int> = context.dataStore.data.map { preferences ->
preferences[pushCounter] ?: 0
}
suspend fun incrementPushCounter() {
context.dataStore.edit { settings ->
val currentCounterValue = settings[pushCounter] ?: 0
settings[pushCounter] = currentCounterValue + 1
}
}
}

View file

@ -41,11 +41,15 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun render(newState: SyncState, fun render(newState: SyncState,
incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus, incrementalSyncStatus: InitialSyncProgressService.Status.IncrementalSyncStatus,
showDebugInfo: Boolean) { pushCounter: Int,
showDebugInfo: Boolean
) {
views.syncStateDebugInfo.isVisible = showDebugInfo views.syncStateDebugInfo.isVisible = showDebugInfo
if (showDebugInfo) { if (showDebugInfo) {
views.syncStateDebugInfo.text = views.syncStateDebugInfoText.text =
"Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncStatus.toHumanReadable()}" "Sync thread : ${newState.toHumanReadable()}\nSync request: ${incrementalSyncStatus.toHumanReadable()}"
views.syncStateDebugInfoPushCounter.text =
"Push: $pushCounter"
} }
views.syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause views.syncStateProgressBar.isVisible = newState is SyncState.Running && newState.afterPause

View file

@ -7,16 +7,33 @@
tools:orientation="vertical" tools:orientation="vertical"
tools:parentTag="android.widget.LinearLayout"> tools:parentTag="android.widget.LinearLayout">
<TextView <FrameLayout
android:id="@+id/syncStateDebugInfo" android:id="@+id/syncStateDebugInfo"
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="monospace"
android:padding="2dp" android:padding="2dp"
android:visibility="gone" android:visibility="gone"
tools:text="debug info" tools:visibility="visible">
tools:visibility="visible" />
<TextView
android:id="@+id/syncStateDebugInfoText"
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="monospace"
tools:text="debug info" />
<TextView
android:id="@+id/syncStateDebugInfoPushCounter"
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:fontFamily="monospace"
android:textStyle="bold"
tools:text="123" />
</FrameLayout>
<!-- Trick to remove surrounding padding (clip from wrapping frame) --> <!-- Trick to remove surrounding padding (clip from wrapping frame) -->
<FrameLayout <FrameLayout