TI: finish the work to identify a session with a sessionId

This commit is contained in:
Benoit Marty 2020-01-07 18:14:17 +01:00
parent e177251ec0
commit 0f7209df1f
35 changed files with 206 additions and 205 deletions

View File

@ -18,6 +18,7 @@ package im.vector.matrix.android.api.auth.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import im.vector.matrix.android.internal.util.md5
/**
* This data class hold credentials user data.
@ -34,3 +35,7 @@ data class Credentials(
// Optional data that may contain info to override home server and/or identity server
@Json(name = "well_known") val wellKnown: WellKnown? = null
)
internal fun Credentials.sessionId(): String {
return (if (deviceId.isNullOrBlank()) userId else "$userId|$deviceId").md5()
}

View File

@ -17,6 +17,7 @@
package im.vector.matrix.android.internal
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.auth.data.sessionId
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.di.MatrixComponent
@ -29,10 +30,11 @@ import javax.inject.Inject
internal class SessionManager @Inject constructor(private val matrixComponent: MatrixComponent,
private val sessionParamsStore: SessionParamsStore) {
// SessionId -> SessionComponent
private val sessionComponents = HashMap<String, SessionComponent>()
fun getSessionComponent(userId: String): SessionComponent? {
val sessionParams = sessionParamsStore.get(userId) ?: return null
fun getSessionComponent(sessionId: String): SessionComponent? {
val sessionParams = sessionParamsStore.get(sessionId) ?: return null
return getOrCreateSessionComponent(sessionParams)
}
@ -40,17 +42,17 @@ internal class SessionManager @Inject constructor(private val matrixComponent: M
return getOrCreateSessionComponent(sessionParams).session()
}
fun releaseSession(userId: String) {
if (sessionComponents.containsKey(userId).not()) {
throw RuntimeException("You don't have a session for the user $userId")
fun releaseSession(sessionId: String) {
if (sessionComponents.containsKey(sessionId).not()) {
throw RuntimeException("You don't have a session for id $sessionId")
}
sessionComponents.remove(userId)?.also {
sessionComponents.remove(sessionId)?.also {
it.session().close()
}
}
private fun getOrCreateSessionComponent(sessionParams: SessionParams): SessionComponent {
return sessionComponents.getOrPut(sessionParams.credentials.userId) {
return sessionComponents.getOrPut(sessionParams.credentials.sessionId()) {
DaggerSessionComponent
.factory()
.create(matrixComponent, sessionParams)

View File

@ -1,23 +0,0 @@
/*
* Copyright 2020 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.matrix.android.internal.auth
import im.vector.matrix.android.internal.util.md5
internal fun createSessionId(userId: String, deviceId: String?): String {
return (if (deviceId.isNullOrBlank()) userId else "$userId|$deviceId").md5()
}

View File

@ -21,7 +21,7 @@ import im.vector.matrix.android.api.auth.data.SessionParams
internal interface SessionParamsStore {
fun get(userId: String): SessionParams?
fun get(sessionId: String): SessionParams?
fun getLast(): SessionParams?
@ -29,11 +29,11 @@ internal interface SessionParamsStore {
suspend fun save(sessionParams: SessionParams)
suspend fun setTokenInvalid(userId: String)
suspend fun setTokenInvalid(sessionId: String)
suspend fun updateCredentials(newCredentials: Credentials)
suspend fun delete(userId: String)
suspend fun delete(sessionId: String)
suspend fun deleteAll()
}

View File

@ -17,7 +17,7 @@
package im.vector.matrix.android.internal.auth.db
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.internal.auth.createSessionId
import im.vector.matrix.android.api.auth.data.sessionId
import im.vector.matrix.android.internal.di.MoshiProvider
import io.realm.DynamicRealm
import io.realm.RealmMigration
@ -71,14 +71,13 @@ internal object AuthRealmMigration : RealmMigration {
?.addField(SessionParamsEntityFields.SESSION_ID, String::class.java)
?.setRequired(SessionParamsEntityFields.SESSION_ID, true)
?.transform {
val userId = it.getString(SessionParamsEntityFields.USER_ID)
val credentialsJson = it.getString(SessionParamsEntityFields.CREDENTIALS_JSON)
val credentials = MoshiProvider.providesMoshi()
.adapter(Credentials::class.java)
.fromJson(credentialsJson)
it.set(SessionParamsEntityFields.SESSION_ID, createSessionId(userId, credentials?.deviceId))
it.set(SessionParamsEntityFields.SESSION_ID, credentials!!.sessionId())
}
?.addPrimaryKey(SessionParamsEntityFields.SESSION_ID)
}

View File

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.auth.db
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.auth.data.sessionId
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.database.awaitTransaction
import im.vector.matrix.android.internal.di.AuthDatabase
@ -42,11 +43,11 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
}
}
override fun get(userId: String): SessionParams? {
override fun get(sessionId: String): SessionParams? {
return Realm.getInstance(realmConfiguration).use { realm ->
realm
.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, userId)
.equalTo(SessionParamsEntityFields.SESSION_ID, sessionId)
.findAll()
.map { mapper.map(it) }
.firstOrNull()
@ -76,17 +77,17 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
}
}
override suspend fun setTokenInvalid(userId: String) {
override suspend fun setTokenInvalid(sessionId: String) {
awaitTransaction(realmConfiguration) { realm ->
val currentSessionParams = realm
.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, userId)
.equalTo(SessionParamsEntityFields.SESSION_ID, sessionId)
.findAll()
.firstOrNull()
if (currentSessionParams == null) {
// Should not happen
"Session param not found for user $userId"
"Session param not found for id $sessionId"
.let { Timber.w(it) }
.also { error(it) }
} else {
@ -99,14 +100,14 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
awaitTransaction(realmConfiguration) { realm ->
val currentSessionParams = realm
.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, newCredentials.userId)
.equalTo(SessionParamsEntityFields.SESSION_ID, newCredentials.sessionId())
.findAll()
.map { mapper.map(it) }
.firstOrNull()
if (currentSessionParams == null) {
// Should not happen
"Session param not found for user ${newCredentials.userId}"
"Session param not found for id ${newCredentials.sessionId()}"
.let { Timber.w(it) }
.also { error(it) }
} else {
@ -123,10 +124,10 @@ internal class RealmSessionParamsStore @Inject constructor(private val mapper: S
}
}
override suspend fun delete(userId: String) {
override suspend fun delete(sessionId: String) {
awaitTransaction(realmConfiguration) {
it.where(SessionParamsEntity::class.java)
.equalTo(SessionParamsEntityFields.USER_ID, userId)
.equalTo(SessionParamsEntityFields.SESSION_ID, sessionId)
.findAll()
.deleteAllFromRealm()
}

View File

@ -20,7 +20,7 @@ import com.squareup.moshi.Moshi
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.internal.auth.createSessionId
import im.vector.matrix.android.api.auth.data.sessionId
import javax.inject.Inject
internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
@ -50,7 +50,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
return null
}
return SessionParamsEntity(
createSessionId(sessionParams.credentials.userId, sessionParams.credentials.deviceId),
sessionParams.credentials.sessionId(),
sessionParams.credentials.userId,
credentialsJson,
homeServerConnectionConfigJson,

View File

@ -22,9 +22,10 @@ import im.vector.matrix.android.internal.di.UserId
import timber.log.Timber
import javax.inject.Inject
internal class SetDeviceVerificationAction @Inject constructor(private val cryptoStore: IMXCryptoStore,
@UserId private val userId: String,
private val keysBackup: KeysBackup) {
internal class SetDeviceVerificationAction @Inject constructor(
private val cryptoStore: IMXCryptoStore,
@UserId private val userId: String,
private val keysBackup: KeysBackup) {
fun handle(verificationStatus: Int, deviceId: String, userId: String) {
val device = cryptoStore.getUserDevice(deviceId, userId)

View File

@ -17,13 +17,13 @@
package im.vector.matrix.android.internal.network
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.di.SessionId
import okhttp3.Interceptor
import okhttp3.Response
import javax.inject.Inject
internal class AccessTokenInterceptor @Inject constructor(
@UserId private val userId: String,
@SessionId private val sessionId: String,
private val sessionParamsStore: SessionParamsStore) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
@ -40,5 +40,5 @@ internal class AccessTokenInterceptor @Inject constructor(
}
private val accessToken
get() = sessionParamsStore.get(userId)?.credentials?.accessToken
get() = sessionParamsStore.get(sessionId)?.credentials?.accessToken
}

View File

@ -44,6 +44,7 @@ import im.vector.matrix.android.api.session.user.UserService
import im.vector.matrix.android.internal.auth.SessionParamsStore
import im.vector.matrix.android.internal.crypto.DefaultCryptoService
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.session.sync.SyncTaskSequencer
import im.vector.matrix.android.internal.session.sync.SyncTokenStore
import im.vector.matrix.android.internal.session.sync.job.SyncThread
@ -59,31 +60,34 @@ import javax.inject.Inject
import javax.inject.Provider
@SessionScope
internal class DefaultSession @Inject constructor(override val sessionParams: SessionParams,
private val context: Context,
private val eventBus: EventBus,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
private val sessionListeners: SessionListeners,
private val roomService: Lazy<RoomService>,
private val roomDirectoryService: Lazy<RoomDirectoryService>,
private val groupService: Lazy<GroupService>,
private val userService: Lazy<UserService>,
private val filterService: Lazy<FilterService>,
private val cacheService: Lazy<CacheService>,
private val signOutService: Lazy<SignOutService>,
private val pushRuleService: Lazy<PushRuleService>,
private val pushersService: Lazy<PushersService>,
private val cryptoService: Lazy<DefaultCryptoService>,
private val fileService: Lazy<FileService>,
private val secureStorageService: Lazy<SecureStorageService>,
private val syncThreadProvider: Provider<SyncThread>,
private val contentUrlResolver: ContentUrlResolver,
private val syncTokenStore: SyncTokenStore,
private val syncTaskSequencer: SyncTaskSequencer,
private val sessionParamsStore: SessionParamsStore,
private val contentUploadProgressTracker: ContentUploadStateTracker,
private val initialSyncProgressService: Lazy<InitialSyncProgressService>,
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>)
internal class DefaultSession @Inject constructor(
override val sessionParams: SessionParams,
private val context: Context,
private val eventBus: EventBus,
@SessionId
private val sessionId: String,
private val liveEntityObservers: Set<@JvmSuppressWildcards LiveEntityObserver>,
private val sessionListeners: SessionListeners,
private val roomService: Lazy<RoomService>,
private val roomDirectoryService: Lazy<RoomDirectoryService>,
private val groupService: Lazy<GroupService>,
private val userService: Lazy<UserService>,
private val filterService: Lazy<FilterService>,
private val cacheService: Lazy<CacheService>,
private val signOutService: Lazy<SignOutService>,
private val pushRuleService: Lazy<PushRuleService>,
private val pushersService: Lazy<PushersService>,
private val cryptoService: Lazy<DefaultCryptoService>,
private val fileService: Lazy<FileService>,
private val secureStorageService: Lazy<SecureStorageService>,
private val syncThreadProvider: Provider<SyncThread>,
private val contentUrlResolver: ContentUrlResolver,
private val syncTokenStore: SyncTokenStore,
private val syncTaskSequencer: SyncTaskSequencer,
private val sessionParamsStore: SessionParamsStore,
private val contentUploadProgressTracker: ContentUploadStateTracker,
private val initialSyncProgressService: Lazy<InitialSyncProgressService>,
private val homeServerCapabilitiesService: Lazy<HomeServerCapabilitiesService>)
: Session,
RoomService by roomService.get(),
RoomDirectoryService by roomDirectoryService.get(),
@ -104,7 +108,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
private var syncThread: SyncThread? = null
override val isOpenable: Boolean
get() = sessionParamsStore.get(myUserId)?.isTokenValid ?: false
get() = sessionParamsStore.get(sessionId)?.isTokenValid ?: false
@MainThread
override fun open() {
@ -115,11 +119,11 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
}
override fun requireBackgroundSync() {
SyncWorker.requireBackgroundSync(context, myUserId)
SyncWorker.requireBackgroundSync(context, sessionId)
}
override fun startAutomaticBackgroundSync(repeatDelay: Long) {
SyncWorker.automaticallyBackgroundSync(context, myUserId, 0, repeatDelay)
SyncWorker.automaticallyBackgroundSync(context, sessionId, 0, repeatDelay)
}
override fun stopAnyBackgroundSync() {
@ -182,7 +186,7 @@ internal class DefaultSession @Inject constructor(override val sessionParams: Se
&& globalError.softLogout) {
// Mark the token has invalid
GlobalScope.launch(Dispatchers.IO) {
sessionParamsStore.setTokenInvalid(myUserId)
sessionParamsStore.setTokenInvalid(sessionId)
}
}

View File

@ -26,11 +26,11 @@ import dagger.multibindings.IntoSet
import im.vector.matrix.android.api.auth.data.Credentials
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
import im.vector.matrix.android.api.auth.data.SessionParams
import im.vector.matrix.android.api.auth.data.sessionId
import im.vector.matrix.android.api.session.InitialSyncProgressService
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService
import im.vector.matrix.android.api.session.securestorage.SecureStorageService
import im.vector.matrix.android.internal.auth.createSessionId
import im.vector.matrix.android.internal.database.LiveEntityObserver
import im.vector.matrix.android.internal.database.SessionRealmConfigurationFactory
import im.vector.matrix.android.internal.di.*
@ -88,7 +88,7 @@ internal abstract class SessionModule {
@SessionId
@Provides
fun providesSessionId(credentials: Credentials): String {
return createSessionId(credentials.userId, credentials.deviceId)
return credentials.sessionId()
}
@JvmStatic

View File

@ -42,7 +42,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val roomId: String,
val event: Event,
val attachment: ContentAttachmentData,
@ -64,7 +64,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
return Result.success(inputData)
}
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val eventId = params.event.eventId ?: return Result.success()
@ -169,7 +169,7 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters) :
Timber.v("handleSuccess $attachmentUrl, work is stopped $isStopped")
contentUploadStateTracker.setSuccess(params.event.eventId!!)
val event = updateEvent(params.event, attachmentUrl, encryptedFileInfo, thumbnailUrl, thumbnailEncryptedFileInfo)
val sendParams = SendEventWorker.Params(params.userId, params.roomId, event)
val sendParams = SendEventWorker.Params(params.sessionId, params.roomId, event)
return Result.success(WorkerParamsFactory.toData(sendParams))
}

View File

@ -29,7 +29,7 @@ internal class GetGroupDataWorker(context: Context, params: WorkerParameters) :
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val groupIds: List<String>,
override val lastFailureMessage: String? = null
) : SessionWorkerParams
@ -40,7 +40,7 @@ internal class GetGroupDataWorker(context: Context, params: WorkerParameters) :
val params = WorkerParamsFactory.fromData<Params>(inputData)
?: return Result.failure()
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val results = params.groupIds.map { groupId ->
runCatching { fetchGroupData(groupId) }

View File

@ -26,7 +26,7 @@ import im.vector.matrix.android.internal.database.awaitTransaction
import im.vector.matrix.android.internal.database.model.GroupEntity
import im.vector.matrix.android.internal.database.model.GroupSummaryEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.worker.WorkManagerUtil
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
@ -37,9 +37,10 @@ import javax.inject.Inject
private const val GET_GROUP_DATA_WORKER = "GET_GROUP_DATA_WORKER"
internal class GroupSummaryUpdater @Inject constructor(private val context: Context,
@UserId private val userId: String,
private val monarchy: Monarchy)
internal class GroupSummaryUpdater @Inject constructor(
private val context: Context,
@SessionId private val sessionId: String,
private val monarchy: Monarchy)
: RealmLiveEntityObserver<GroupEntity>(monarchy.realmConfiguration) {
override val query = Monarchy.Query { GroupEntity.where(it) }
@ -51,9 +52,9 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
.mapNotNull { results[it] }
fetchGroupsData(modifiedGroupEntity
.filter { it.membership == Membership.JOIN || it.membership == Membership.INVITE }
.map { it.groupId }
.toList())
.filter { it.membership == Membership.JOIN || it.membership == Membership.INVITE }
.map { it.groupId }
.toList())
modifiedGroupEntity
.filter { it.membership == Membership.LEAVE }
@ -67,7 +68,7 @@ internal class GroupSummaryUpdater @Inject constructor(private val context: Cont
}
private fun fetchGroupsData(groupIds: List<String>) {
val getGroupDataWorkerParams = GetGroupDataWorker.Params(userId, groupIds)
val getGroupDataWorkerParams = GetGroupDataWorker.Params(sessionId, groupIds)
val workData = WorkerParamsFactory.toData(getGroupDataWorkerParams)

View File

@ -27,6 +27,7 @@ import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.util.awaitTransaction
import im.vector.matrix.android.internal.worker.SessionWorkerParams
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import im.vector.matrix.android.internal.worker.getSessionComponent
import org.greenrobot.eventbus.EventBus
@ -37,9 +38,10 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
@JsonClass(generateAdapter = true)
internal data class Params(
override val sessionId: String,
val pusher: JsonPusher,
val userId: String
)
override val lastFailureMessage: String? = null
) : SessionWorkerParams
@Inject lateinit var pushersAPI: PushersAPI
@Inject lateinit var monarchy: Monarchy
@ -49,7 +51,7 @@ internal class AddHttpPusherWorker(context: Context, params: WorkerParameters)
val params = WorkerParamsFactory.fromData<Params>(inputData)
?: return Result.failure()
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val pusher = params.pusher

View File

@ -26,22 +26,23 @@ import im.vector.matrix.android.api.session.pushers.PushersService
import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.PusherEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.worker.WorkManagerUtil
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import java.util.UUID
import java.util.*
import java.util.concurrent.TimeUnit
import javax.inject.Inject
internal class DefaultPusherService @Inject constructor(private val context: Context,
private val monarchy: Monarchy,
@UserId private val userId: String,
private val getPusherTask: GetPushersTask,
private val removePusherTask: RemovePusherTask,
private val taskExecutor: TaskExecutor
internal class DefaultPusherService @Inject constructor(
private val context: Context,
private val monarchy: Monarchy,
@SessionId private val sessionId: String,
private val getPusherTask: GetPushersTask,
private val removePusherTask: RemovePusherTask,
private val taskExecutor: TaskExecutor
) : PushersService {
override fun refreshPushers() {
@ -65,7 +66,7 @@ internal class DefaultPusherService @Inject constructor(private val context: Con
data = JsonPusherData(url, if (withEventIdOnly) PushersService.EVENT_ID_ONLY else null),
append = append)
val params = AddHttpPusherWorker.Params(pusher, userId)
val params = AddHttpPusherWorker.Params(sessionId, pusher)
val request = matrixOneTimeWorkRequestBuilder<AddHttpPusherWorker>()
.setConstraints(WorkManagerUtil.workConstraints)

View File

@ -36,9 +36,10 @@ import javax.inject.Inject
* The summaries can then be extracted and added (as a decoration) to a TimelineEvent for final display.
*/
internal class EventRelationsAggregationUpdater @Inject constructor(@SessionDatabase realmConfiguration: RealmConfiguration,
@UserId private val userId: String,
private val task: EventRelationsAggregationTask) :
internal class EventRelationsAggregationUpdater @Inject constructor(
@SessionDatabase realmConfiguration: RealmConfiguration,
@UserId private val userId: String,
private val task: EventRelationsAggregationTask) :
RealmLiveEntityObserver<EventEntity>(realmConfiguration) {
override val query = Monarchy.Query<EventEntity> {

View File

@ -29,10 +29,6 @@ import im.vector.matrix.android.internal.database.model.EventEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.*
import im.vector.matrix.android.internal.database.query.isEventRead
import im.vector.matrix.android.internal.database.query.latestEvent
import im.vector.matrix.android.internal.database.query.prev
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.session.room.membership.RoomDisplayNameResolver
import im.vector.matrix.android.internal.session.room.membership.RoomMembers
@ -41,10 +37,11 @@ import im.vector.matrix.android.internal.session.sync.model.RoomSyncUnreadNotifi
import io.realm.Realm
import javax.inject.Inject
internal class RoomSummaryUpdater @Inject constructor(@UserId private val userId: String,
private val roomDisplayNameResolver: RoomDisplayNameResolver,
private val roomAvatarResolver: RoomAvatarResolver,
private val monarchy: Monarchy) {
internal class RoomSummaryUpdater @Inject constructor(
@UserId private val userId: String,
private val roomDisplayNameResolver: RoomDisplayNameResolver,
private val roomAvatarResolver: RoomAvatarResolver,
private val monarchy: Monarchy) {
// TODO: maybe allow user of SDK to give that list
private val PREVIEWABLE_TYPES = listOf(

View File

@ -36,12 +36,13 @@ import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith
internal class DefaultReadService @AssistedInject constructor(@Assisted private val roomId: String,
private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor,
private val setReadMarkersTask: SetReadMarkersTask,
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
@UserId private val userId: String
internal class DefaultReadService @AssistedInject constructor(
@Assisted private val roomId: String,
private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor,
private val setReadMarkersTask: SetReadMarkersTask,
private val readReceiptsSummaryMapper: ReadReceiptsSummaryMapper,
@UserId private val userId: String
) : ReadService {
@AssistedInject.Factory

View File

@ -38,7 +38,7 @@ import im.vector.matrix.android.internal.database.mapper.asDomain
import im.vector.matrix.android.internal.database.model.EventAnnotationsSummaryEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.session.room.send.EncryptEventWorker
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
import im.vector.matrix.android.internal.session.room.send.RedactEventWorker
@ -51,16 +51,17 @@ import im.vector.matrix.android.internal.util.fetchCopyMap
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
import timber.log.Timber
internal class DefaultRelationService @AssistedInject constructor(@Assisted private val roomId: String,
private val context: Context,
@UserId private val userId: String,
private val eventFactory: LocalEchoEventFactory,
private val cryptoService: CryptoService,
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
private val fetchEditHistoryTask: FetchEditHistoryTask,
private val timelineEventMapper: TimelineEventMapper,
private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor)
internal class DefaultRelationService @AssistedInject constructor(
@Assisted private val roomId: String,
private val context: Context,
@SessionId private val sessionId: String,
private val eventFactory: LocalEchoEventFactory,
private val cryptoService: CryptoService,
private val findReactionEventForUndoTask: FindReactionEventForUndoTask,
private val fetchEditHistoryTask: FetchEditHistoryTask,
private val timelineEventMapper: TimelineEventMapper,
private val monarchy: Monarchy,
private val taskExecutor: TaskExecutor)
: RelationService {
@AssistedInject.Factory
@ -125,7 +126,7 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv
// TODO duplicate with send service?
private fun createRedactEventWork(localEvent: Event, eventId: String, reason: String?): OneTimeWorkRequest {
val sendContentWorkerParams = RedactEventWorker.Params(
userId,
sessionId,
localEvent.eventId!!,
roomId,
eventId,
@ -204,13 +205,13 @@ internal class DefaultRelationService @AssistedInject constructor(@Assisted priv
private fun createEncryptEventWork(event: Event, keepKeys: List<String>?): OneTimeWorkRequest {
// Same parameter
val params = EncryptEventWorker.Params(userId, roomId, event, keepKeys)
val params = EncryptEventWorker.Params(sessionId, roomId, event, keepKeys)
val sendWorkData = WorkerParamsFactory.toData(params)
return TimelineSendEventWorkCommon.createWork<EncryptEventWorker>(sendWorkData, true)
}
private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest {
val sendContentWorkerParams = SendEventWorker.Params(userId, roomId, event)
val sendContentWorkerParams = SendEventWorker.Params(sessionId, roomId, event)
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
return TimelineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
}

View File

@ -38,8 +38,9 @@ internal interface FindReactionEventForUndoTask : Task<FindReactionEventForUndoT
)
}
internal class DefaultFindReactionEventForUndoTask @Inject constructor(private val monarchy: Monarchy,
@UserId private val userId: String) : FindReactionEventForUndoTask {
internal class DefaultFindReactionEventForUndoTask @Inject constructor(
private val monarchy: Monarchy,
@UserId private val userId: String) : FindReactionEventForUndoTask {
override suspend fun execute(params: FindReactionEventForUndoTask.Params): FindReactionEventForUndoTask.Result {
val eventId = Realm.getInstance(monarchy.realmConfiguration).use { realm ->
@ -55,7 +56,7 @@ internal class DefaultFindReactionEventForUndoTask @Inject constructor(private v
.equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction)
.findFirst() ?: return null
// want to find the event orignated by me!
// want to find the event originated by me!
return rase.sourceEvents
.asSequence()
.mapNotNull {

View File

@ -33,15 +33,16 @@ import im.vector.matrix.android.internal.worker.getSessionComponent
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
// TODO This is not used. Delete?
internal class SendRelationWorker(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val roomId: String,
val event: Event,
val relationType: String? = null,
override val lastFailureMessage: String?
override val lastFailureMessage: String? = null
) : SessionWorkerParams
@Inject lateinit var roomAPI: RoomAPI
@ -56,7 +57,7 @@ internal class SendRelationWorker(context: Context, params: WorkerParameters) :
return Result.success(inputData)
}
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val localEvent = params.event

View File

@ -37,7 +37,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates
import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.session.content.UploadContentWorker
import im.vector.matrix.android.internal.session.room.timeline.TimelineSendEventWorkCommon
import im.vector.matrix.android.internal.util.CancelableWork
@ -53,12 +53,13 @@ import java.util.concurrent.TimeUnit
private const val UPLOAD_WORK = "UPLOAD_WORK"
private const val BACKOFF_DELAY = 10_000L
internal class DefaultSendService @AssistedInject constructor(@Assisted private val roomId: String,
private val context: Context,
@UserId private val userId: String,
private val localEchoEventFactory: LocalEchoEventFactory,
private val cryptoService: CryptoService,
private val monarchy: Monarchy
internal class DefaultSendService @AssistedInject constructor(
@Assisted private val roomId: String,
private val context: Context,
@SessionId private val sessionId: String,
private val localEchoEventFactory: LocalEchoEventFactory,
private val cryptoService: CryptoService,
private val monarchy: Monarchy
) : SendService {
@AssistedInject.Factory
@ -285,7 +286,7 @@ internal class DefaultSendService @AssistedInject constructor(@Assisted private
private fun createEncryptEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest {
// Same parameter
val params = EncryptEventWorker.Params(userId, roomId, event)
val params = EncryptEventWorker.Params(sessionId, roomId, event)
val sendWorkData = WorkerParamsFactory.toData(params)
return matrixOneTimeWorkRequestBuilder<EncryptEventWorker>()
@ -297,7 +298,7 @@ internal class DefaultSendService @AssistedInject constructor(@Assisted private
}
private fun createSendEventWork(event: Event, startChain: Boolean): OneTimeWorkRequest {
val sendContentWorkerParams = SendEventWorker.Params(userId, roomId, event)
val sendContentWorkerParams = SendEventWorker.Params(sessionId, roomId, event)
val sendWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
return TimelineSendEventWorkCommon.createWork<SendEventWorker>(sendWorkData, startChain)
@ -307,7 +308,7 @@ internal class DefaultSendService @AssistedInject constructor(@Assisted private
val redactEvent = localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason).also {
saveLocalEcho(it)
}
val sendContentWorkerParams = RedactEventWorker.Params(userId, redactEvent.eventId!!, roomId, event.eventId, reason)
val sendContentWorkerParams = RedactEventWorker.Params(sessionId, redactEvent.eventId!!, roomId, event.eventId, reason)
val redactWorkData = WorkerParamsFactory.toData(sendContentWorkerParams)
return TimelineSendEventWorkCommon.createWork<RedactEventWorker>(redactWorkData, true)
}
@ -316,7 +317,7 @@ internal class DefaultSendService @AssistedInject constructor(@Assisted private
attachment: ContentAttachmentData,
isRoomEncrypted: Boolean,
startChain: Boolean): OneTimeWorkRequest {
val uploadMediaWorkerParams = UploadContentWorker.Params(userId, roomId, event, attachment, isRoomEncrypted)
val uploadMediaWorkerParams = UploadContentWorker.Params(sessionId, roomId, event, attachment, isRoomEncrypted)
val uploadWorkData = WorkerParamsFactory.toData(uploadMediaWorkerParams)
return matrixOneTimeWorkRequestBuilder<UploadContentWorker>()

View File

@ -37,7 +37,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val roomId: String,
val event: Event,
/**Do not encrypt these keys, keep them as is in encrypted content (e.g. m.relates_to)*/
@ -61,7 +61,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
return Result.success(inputData)
}
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val localEvent = params.event
@ -97,7 +97,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
type = safeResult.eventType,
content = safeResult.eventContent
)
val nextWorkerParams = SendEventWorker.Params(params.userId, params.roomId, encryptedEvent)
val nextWorkerParams = SendEventWorker.Params(params.sessionId, params.roomId, encryptedEvent)
return Result.success(WorkerParamsFactory.toData(nextWorkerParams))
} else {
val sendState = when (error) {
@ -106,7 +106,7 @@ internal class EncryptEventWorker(context: Context, params: WorkerParameters)
}
localEchoUpdater.updateSendState(localEvent.eventId, sendState)
// always return success, or the chain will be stuck for ever!
val nextWorkerParams = SendEventWorker.Params(params.userId, params.roomId, localEvent, error?.localizedMessage
val nextWorkerParams = SendEventWorker.Params(params.sessionId, params.roomId, localEvent, error?.localizedMessage
?: "Error")
return Result.success(WorkerParamsFactory.toData(nextWorkerParams))
}

View File

@ -32,7 +32,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val txID: String,
val roomId: String,
val eventId: String,
@ -52,7 +52,7 @@ internal class RedactEventWorker(context: Context, params: WorkerParameters) : C
return Result.success(inputData)
}
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val eventId = params.eventId

View File

@ -38,7 +38,7 @@ internal class SendEventWorker constructor(context: Context, params: WorkerParam
@JsonClass(generateAdapter = true)
internal data class Params(
override val userId: String,
override val sessionId: String,
val roomId: String,
val event: Event,
override val lastFailureMessage: String? = null
@ -52,7 +52,7 @@ internal class SendEventWorker constructor(context: Context, params: WorkerParam
val params = WorkerParamsFactory.fromData<Params>(inputData)
?: return Result.success()
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
val event = params.event

View File

@ -23,6 +23,8 @@ import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
// TODO Add parent task
internal class GetEventTask @Inject constructor(
private val roomAPI: RoomAPI,
private val eventBus: EventBus

View File

@ -46,7 +46,7 @@ internal interface SignOutTask : Task<SignOutTask.Params, Unit> {
internal class DefaultSignOutTask @Inject constructor(
private val context: Context,
@UserId private val userId: String,
@SessionId private val sessionId: String,
private val signOutAPI: SignOutAPI,
private val sessionManager: SessionManager,
private val sessionParamsStore: SessionParamsStore,
@ -83,13 +83,13 @@ internal class DefaultSignOutTask @Inject constructor(
}
Timber.d("SignOut: release session...")
sessionManager.releaseSession(userId)
sessionManager.releaseSession(sessionId)
Timber.d("SignOut: cancel pending works...")
WorkManagerUtil.cancelAllWorks(context)
Timber.d("SignOut: delete session params...")
sessionParamsStore.delete(userId)
sessionParamsStore.delete(sessionId)
Timber.d("SignOut: clear session data...")
clearSessionDataTask.execute(Unit)

View File

@ -38,10 +38,11 @@ import io.realm.RealmList
import timber.log.Timber
import javax.inject.Inject
internal class UserAccountDataSyncHandler @Inject constructor(private val monarchy: Monarchy,
@UserId private val userId: String,
private val directChatsHelper: DirectChatsHelper,
private val updateUserAccountDataTask: UpdateUserAccountDataTask) {
internal class UserAccountDataSyncHandler @Inject constructor(
private val monarchy: Monarchy,
@UserId private val userId: String,
private val directChatsHelper: DirectChatsHelper,
private val updateUserAccountDataTask: UpdateUserAccountDataTask) {
fun handle(realm: Realm, accountData: UserAccountDataSync?) {
accountData?.list?.forEach {

View File

@ -39,7 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean
*/
abstract class SyncService : Service() {
private var userId: String? = null
private var sessionId: String? = null
private var mIsSelfDestroyed: Boolean = false
private var isInitialSync: Boolean = false
@ -58,11 +58,11 @@ abstract class SyncService : Service() {
Timber.i("onStartCommand $intent")
intent?.let {
val matrix = Matrix.getInstance(applicationContext)
val safeUserId = it.getStringExtra(EXTRA_USER_ID) ?: return@let
val sessionComponent = matrix.sessionManager.getSessionComponent(safeUserId)
val safeSessionId = it.getStringExtra(EXTRA_SESSION_ID) ?: return@let
val sessionComponent = matrix.sessionManager.getSessionComponent(safeSessionId)
?: return@let
session = sessionComponent.session()
userId = safeUserId
sessionId = safeSessionId
syncTask = sessionComponent.syncTask()
isInitialSync = !session.hasAlreadySynced()
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
@ -101,7 +101,7 @@ abstract class SyncService : Service() {
private suspend fun doSync() {
if (!networkConnectivityChecker.hasInternetAccess()) {
Timber.v("No network reschedule to avoid wasting resources")
userId?.also {
sessionId?.also {
onRescheduleAsked(it, isInitialSync, delay = 10_000L)
}
stopMe()
@ -131,14 +131,14 @@ abstract class SyncService : Service() {
abstract fun onStart(isInitialSync: Boolean)
abstract fun onRescheduleAsked(userId: String, isInitialSync: Boolean, delay: Long)
abstract fun onRescheduleAsked(sessionId: String, isInitialSync: Boolean, delay: Long)
override fun onBind(intent: Intent?): IBinder? {
return null
}
companion object {
const val EXTRA_USER_ID = "EXTRA_USER_ID"
const val EXTRA_SESSION_ID = "EXTRA_SESSION_ID"
private const val TIME_OUT = 0L
private const val DELAY_FAILURE = 5_000L
}

View File

@ -22,6 +22,7 @@ import im.vector.matrix.android.api.failure.isTokenError
import im.vector.matrix.android.internal.network.NetworkConnectivityChecker
import im.vector.matrix.android.internal.session.sync.SyncTask
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.worker.SessionWorkerParams
import im.vector.matrix.android.internal.worker.WorkManagerUtil
import im.vector.matrix.android.internal.worker.WorkManagerUtil.matrixOneTimeWorkRequestBuilder
import im.vector.matrix.android.internal.worker.WorkerParamsFactory
@ -38,10 +39,11 @@ internal class SyncWorker(context: Context,
@JsonClass(generateAdapter = true)
internal data class Params(
val userId: String,
override val sessionId: String,
val timeout: Long = DEFAULT_LONG_POOL_TIMEOUT,
val automaticallyRetry: Boolean = false
)
val automaticallyRetry: Boolean = false,
override val lastFailureMessage: String? = null
) : SessionWorkerParams
@Inject lateinit var syncTask: SyncTask
@Inject lateinit var taskExecutor: TaskExecutor
@ -50,7 +52,7 @@ internal class SyncWorker(context: Context,
override suspend fun doWork(): Result {
Timber.i("Sync work starting")
val params = WorkerParamsFactory.fromData<Params>(inputData) ?: return Result.success()
val sessionComponent = getSessionComponent(params.userId) ?: return Result.success()
val sessionComponent = getSessionComponent(params.sessionId) ?: return Result.success()
sessionComponent.inject(this)
return runCatching {
doSync(params.timeout)
@ -75,8 +77,8 @@ internal class SyncWorker(context: Context,
const val BG_SYNC_WORK_NAME = "BG_SYNCP"
fun requireBackgroundSync(context: Context, userId: String, serverTimeout: Long = 0) {
val data = WorkerParamsFactory.toData(Params(userId, serverTimeout, false))
fun requireBackgroundSync(context: Context, sessionId: String, serverTimeout: Long = 0) {
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, false))
val workRequest = matrixOneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(WorkManagerUtil.workConstraints)
.setBackoffCriteria(BackoffPolicy.LINEAR, 1_000, TimeUnit.MILLISECONDS)
@ -85,8 +87,8 @@ internal class SyncWorker(context: Context,
WorkManager.getInstance(context).enqueueUniqueWork(BG_SYNC_WORK_NAME, ExistingWorkPolicy.REPLACE, workRequest)
}
fun automaticallyBackgroundSync(context: Context, userId: String, serverTimeout: Long = 0, delay: Long = 30_000) {
val data = WorkerParamsFactory.toData(Params(userId, serverTimeout, true))
fun automaticallyBackgroundSync(context: Context, sessionId: String, serverTimeout: Long = 0, delay: Long = 30_000) {
val data = WorkerParamsFactory.toData(Params(sessionId, serverTimeout, true))
val workRequest = matrixOneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(WorkManagerUtil.workConstraints)
.setInputData(data)

View File

@ -17,7 +17,7 @@
package im.vector.matrix.android.internal.worker
interface SessionWorkerParams {
val userId: String
val sessionId: String
// Null is no error occurs. When chaining Workers, first step is to check that there is no lastFailureMessage from the previous workers
val lastFailureMessage: String?

View File

@ -20,6 +20,6 @@ import androidx.work.ListenableWorker
import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.internal.session.SessionComponent
internal fun ListenableWorker.getSessionComponent(userId: String): SessionComponent? {
return Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(userId)
internal fun ListenableWorker.getSessionComponent(sessionId: String): SessionComponent? {
return Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(sessionId)
}

View File

@ -31,17 +31,17 @@ import timber.log.Timber
class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
// Aquire a lock to give enough time for the sync :/
// Acquire a lock to give enough time for the sync :/
(context.getSystemService(Context.POWER_SERVICE) as PowerManager).run {
newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "riotx:fdroidSynclock").apply {
acquire((10_000).toLong())
}
}
val userId = intent.getStringExtra(SyncService.EXTRA_USER_ID)
val sessionId = intent.getStringExtra(SyncService.EXTRA_SESSION_ID)
// This method is called when the BroadcastReceiver is receiving an Intent broadcast.
Timber.d("RestartBroadcastReceiver received intent")
VectorSyncService.newIntent(context, userId).also {
VectorSyncService.newIntent(context, sessionId).let {
try {
ContextCompat.startForegroundService(context, it)
} catch (ex: Throwable) {
@ -50,7 +50,7 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
}
}
scheduleAlarm(context, userId, 30_000L)
scheduleAlarm(context, sessionId, 30_000L)
Timber.i("Alarm scheduled to restart service")
}
@ -58,10 +58,10 @@ class AlarmSyncBroadcastReceiver : BroadcastReceiver() {
companion object {
private const val REQUEST_CODE = 0
fun scheduleAlarm(context: Context, userId: String, delay: Long) {
fun scheduleAlarm(context: Context, sessionId: String, delay: Long) {
// Reschedule
val intent = Intent(context, AlarmSyncBroadcastReceiver::class.java).apply {
putExtra(SyncService.EXTRA_USER_ID, userId)
putExtra(SyncService.EXTRA_SESSION_ID, sessionId)
}
val pIntent = PendingIntent.getBroadcast(context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val firstMillis = System.currentTimeMillis() + delay

View File

@ -30,9 +30,9 @@ class VectorSyncService : SyncService() {
companion object {
fun newIntent(context: Context, userId: String): Intent {
fun newIntent(context: Context, sessionId: String): Intent {
return Intent(context, VectorSyncService::class.java).also {
it.putExtra(EXTRA_USER_ID, userId)
it.putExtra(EXTRA_SESSION_ID, sessionId)
}
}
}
@ -54,25 +54,25 @@ class VectorSyncService : SyncService() {
startForeground(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE, notification)
}
override fun onRescheduleAsked(userId: String, isInitialSync: Boolean, delay: Long) {
reschedule(userId, delay)
override fun onRescheduleAsked(sessionId: String, isInitialSync: Boolean, delay: Long) {
reschedule(sessionId, delay)
}
override fun onDestroy() {
removeForegroundNotif()
removeForegroundNotification()
super.onDestroy()
}
private fun removeForegroundNotif() {
private fun removeForegroundNotification() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancel(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE)
}
private fun reschedule(userId: String, delay: Long) {
private fun reschedule(sessionId: String, delay: Long) {
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
PendingIntent.getForegroundService(this, 0, newIntent(this, userId), 0)
PendingIntent.getForegroundService(this, 0, newIntent(this, sessionId), 0)
} else {
PendingIntent.getService(this, 0, newIntent(this, userId), 0)
PendingIntent.getService(this, 0, newIntent(this, sessionId), 0)
}
val firstMillis = System.currentTimeMillis() + delay
val alarmMgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager