Эх сурвалжийг харах

Migrate AccountVerificationController from requery to room

Signed-off-by: Andy Scherzinger <info@andy-scherzinger.de>
Andy Scherzinger 2 жил өмнө
parent
commit
6e05056b2e

+ 31 - 29
app/src/main/java/com/nextcloud/talk/controllers/AccountVerificationController.kt

@@ -26,6 +26,7 @@ import android.content.pm.ActivityInfo
 import android.os.Bundle
 import android.os.Handler
 import android.text.TextUtils
+import android.util.Log
 import android.view.View
 import androidx.work.Data
 import androidx.work.OneTimeWorkRequest
@@ -39,15 +40,16 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.controllers.base.NewBaseController
 import com.nextcloud.talk.controllers.util.viewBinding
+import com.nextcloud.talk.data.user.model.User
 import com.nextcloud.talk.databinding.ControllerAccountVerificationBinding
 import com.nextcloud.talk.events.EventStatus
 import com.nextcloud.talk.jobs.CapabilitiesWorker
 import com.nextcloud.talk.jobs.PushRegistrationWorker
 import com.nextcloud.talk.jobs.SignalingSettingsWorker
-import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall
 import com.nextcloud.talk.models.json.generic.Status
 import com.nextcloud.talk.models.json.userprofile.UserProfileOverall
+import com.nextcloud.talk.users.UserManager
 import com.nextcloud.talk.utils.ApiUtils
 import com.nextcloud.talk.utils.ClosedInterfaceImpl
 import com.nextcloud.talk.utils.UriUtils
@@ -57,9 +59,8 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ORIGINAL_PROTOCOL
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_TOKEN
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USERNAME
-import com.nextcloud.talk.utils.database.user.UserUtils
 import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder
-import io.reactivex.CompletableObserver
+import io.reactivex.MaybeObserver
 import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
@@ -68,7 +69,6 @@ import org.greenrobot.eventbus.EventBus
 import org.greenrobot.eventbus.Subscribe
 import org.greenrobot.eventbus.ThreadMode
 import java.net.CookieManager
-import java.util.ArrayList
 import javax.inject.Inject
 
 @AutoInjector(NextcloudTalkApplication::class)
@@ -83,7 +83,7 @@ class AccountVerificationController(args: Bundle? = null) :
     lateinit var ncApi: NcApi
 
     @Inject
-    lateinit var userUtils: UserUtils
+    lateinit var userManager: UserManager
 
     @Inject
     lateinit var cookieManager: CookieManager
@@ -248,21 +248,30 @@ class AccountVerificationController(args: Bundle? = null) :
     }
 
     private fun storeProfile(displayName: String?, userId: String) {
-        userUtils.createOrUpdateUser(
-            username, token,
-            baseUrl, displayName, null, java.lang.Boolean.TRUE,
-            userId, null, null,
-            appPreferences!!.temporaryClientCertAlias, null
+        userManager.storeProfile(
+            username,
+            UserManager.UserAttributes(
+                id = null,
+                serverUrl = baseUrl,
+                currentUser = true,
+                userId = userId,
+                token = token,
+                displayName = displayName,
+                pushConfigurationState = null,
+                capabilities = null,
+                certificateAlias = appPreferences!!.temporaryClientCertAlias,
+                externalSignalingServer = null
+            )
         )
             .subscribeOn(Schedulers.io())
-            .subscribe(object : Observer<UserEntity> {
+            .subscribe(object : MaybeObserver<User> {
                 override fun onSubscribe(d: Disposable) {
                     disposables.add(d)
                 }
 
                 @SuppressLint("SetTextI18n")
-                override fun onNext(userEntity: UserEntity) {
-                    internalAccountId = userEntity.id
+                override fun onSuccess(user: User) {
+                    internalAccountId = user.id!!
                     if (ClosedInterfaceImpl().isGooglePlayServicesAvailable) {
                         registerForPush()
                     } else {
@@ -283,7 +292,7 @@ class AccountVerificationController(args: Bundle? = null) :
                         """
                             ${binding.progressText.text}
                     """.trimIndent() +
-                        resources!!.getString(R.string.nc_display_name_not_stored)
+                            resources!!.getString(R.string.nc_display_name_not_stored)
                     abortVerification()
                 }
 
@@ -431,10 +440,11 @@ class AccountVerificationController(args: Bundle? = null) :
 
     private fun proceedWithLogin() {
         cookieManager.cookieStore.removeAll()
-        userUtils.disableAllUsersWithoutId(internalAccountId)
+        val userDisabledCount = userManager.disableAllUsersWithoutId(internalAccountId).blockingGet()
+        Log.d(TAG, "Disabled $userDisabledCount users that had no id")
         if (activity != null) {
             activity!!.runOnUiThread {
-                if (userUtils.users.size == 1) {
+                if (userManager.users.blockingGet().size == 1) {
                     router.setRoot(
                         RouterTransaction.with(ConversationsListController(Bundle()))
                             .pushChangeHandler(HorizontalChangeHandler())
@@ -472,18 +482,10 @@ class AccountVerificationController(args: Bundle? = null) :
     private fun abortVerification() {
         if (!isAccountImport) {
             if (internalAccountId != -1L) {
-                userUtils.deleteUserWithId(internalAccountId).subscribe(object : CompletableObserver {
-                    override fun onSubscribe(d: Disposable) {
-                        // unused atm
-                    }
-                    override fun onComplete() {
+                val count = userManager.deleteUser(internalAccountId)
+                if (count > 0) {
                         activity?.runOnUiThread { Handler().postDelayed({ router.popToRoot() }, DELAY_IN_MILLIS) }
-                    }
-
-                    override fun onError(e: Throwable) {
-                        // unused atm
-                    }
-                })
+                }
             } else {
                 activity?.runOnUiThread { Handler().postDelayed({ router.popToRoot() }, DELAY_IN_MILLIS) }
             }
@@ -498,7 +500,7 @@ class AccountVerificationController(args: Bundle? = null) :
                             router.popToRoot()
                         }
                     } else {
-                        if (userUtils.anyUserExists()) {
+                        if (userManager.users.blockingGet().isNotEmpty()) {
                             router.setRoot(
                                 RouterTransaction.with(ConversationsListController(Bundle()))
                                     .pushChangeHandler(HorizontalChangeHandler())
@@ -518,7 +520,7 @@ class AccountVerificationController(args: Bundle? = null) :
     }
 
     companion object {
-        const val TAG = "AccountVerificationController"
+        const val TAG = "AccountVerification"
         const val DELAY_IN_MILLIS: Long = 7500
     }
 

+ 3 - 2
app/src/main/java/com/nextcloud/talk/data/user/UsersDao.kt

@@ -24,6 +24,7 @@ package com.nextcloud.talk.data.user
 
 import android.util.Log
 import androidx.room.Dao
+import androidx.room.Delete
 import androidx.room.Insert
 import androidx.room.OnConflictStrategy
 import androidx.room.Query
@@ -45,8 +46,8 @@ abstract class UsersDao {
     @Query("SELECT * FROM User where current = 1")
     abstract fun getActiveUserSynchronously(): UserEntity?
 
-    @Query("DELETE FROM User WHERE id = :id")
-    abstract fun deleteUserWithId(id: Long)
+    @Delete
+    abstract fun deleteUser(user: UserEntity): Int
 
     @Update
     abstract fun updateUser(user: UserEntity): Int

+ 1 - 1
app/src/main/java/com/nextcloud/talk/data/user/UsersRepository.kt

@@ -40,7 +40,7 @@ interface UsersRepository {
     fun updateUser(user: User): Int
     fun insertUser(user: User): Long
     fun setUserAsActiveWithId(id: Long): Single<Boolean>
-    fun deleteUserWithId(id: Long)
+    fun deleteUser(user: User): Int
     fun setAnyUserAsActive(): Boolean
     fun markUserForDeletion(id: Long): Boolean
 }

+ 2 - 2
app/src/main/java/com/nextcloud/talk/data/user/UsersRepositoryImpl.kt

@@ -77,8 +77,8 @@ class UsersRepositoryImpl(private val usersDao: UsersDao) : UsersRepository {
         return Single.just(usersDao.setUserAsActiveWithId(id))
     }
 
-    override fun deleteUserWithId(id: Long) {
-        usersDao.deleteUserWithId(id)
+    override fun deleteUser(user: User): Int {
+        return usersDao.deleteUser(UserMapper.toEntity(user))
     }
 
     override fun setAnyUserAsActive(): Boolean {

+ 74 - 17
app/src/main/java/com/nextcloud/talk/users/UserManager.kt

@@ -22,6 +22,7 @@
 package com.nextcloud.talk.users
 
 import android.text.TextUtils
+import android.util.Log
 import com.bluelinelabs.logansquare.LoganSquare
 import com.nextcloud.talk.data.user.UsersRepository
 import com.nextcloud.talk.data.user.model.User
@@ -31,6 +32,7 @@ import com.nextcloud.talk.models.json.push.PushConfigurationState
 import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew
 import io.reactivex.Maybe
 import io.reactivex.Single
+import java.lang.Boolean.FALSE
 import java.lang.Boolean.TRUE
 
 @Suppress("TooManyFunctions")
@@ -41,9 +43,10 @@ class UserManager internal constructor(private val userRepository: UsersReposito
     val usersScheduledForDeletion: Single<List<User>>
         get() = userRepository.getUsersScheduledForDeletion()
 
-    private fun setAnyUserAndSetAsActive(): Single<User> {
+    private fun getAnyUserAndSetAsActive(): Single<User> {
         val results = userRepository.getUsersNotScheduledForDeletion()
 
+        // TODO needs to return Empty in case no user was found (and set active)
         return results.map { users ->
             users
                 .firstOrNull()
@@ -60,12 +63,8 @@ class UserManager internal constructor(private val userRepository: UsersReposito
             return userRepository.getActiveUser()
         }
 
-    fun deleteUser(internalId: Long) {
-        userRepository.deleteUserWithId(internalId)
-    }
-
-    fun deleteUserWithId(internalId: Long) {
-        userRepository.deleteUserWithId(internalId)
+    fun deleteUser(internalId: Long): Int {
+        return userRepository.deleteUser(userRepository.getUserWithId(internalId).blockingGet())
     }
 
     fun getUserById(userId: String): Maybe<User> {
@@ -93,7 +92,15 @@ class UserManager internal constructor(private val userRepository: UsersReposito
     }
 
     fun checkIfUserIsScheduledForDeletion(username: String, server: String): Maybe<Boolean> {
-        return userRepository.getUserWithUsernameAndServer(username, server).map { it.scheduledForDeletion }
+        return userRepository
+            .getUserWithUsernameAndServer(username, server)
+            .switchIfEmpty(Maybe.empty())
+            .map { user: User? ->
+                when (user) {
+                    null -> FALSE
+                    else -> user.scheduledForDeletion
+                }
+            }
     }
 
     fun getUserWithInternalId(id: Long): Maybe<User> {
@@ -101,10 +108,19 @@ class UserManager internal constructor(private val userRepository: UsersReposito
     }
 
     fun getIfUserWithUsernameAndServer(username: String, server: String): Maybe<Boolean> {
-        return userRepository.getUserWithUsernameAndServer(username, server).map { TRUE }
+        return userRepository
+            .getUserWithUsernameAndServer(username, server)
+            .map { user: User? ->
+                when (user) {
+                    null -> FALSE
+                    else -> TRUE
+                }
+            }
     }
 
     fun scheduleUserForDeletionWithId(id: Long): Single<Boolean> {
+        // TODO needs to return false in case getAnyUserAndSetAsActive doesn't return a user
+        // or getUserWithId(id) doesn't return a user
         return userRepository.getUserWithId(id).map { user ->
             user.scheduledForDeletion = true
             user.current = false
@@ -112,7 +128,7 @@ class UserManager internal constructor(private val userRepository: UsersReposito
         }
             .toSingle()
             .flatMap {
-                setAnyUserAndSetAsActive()
+                getAnyUserAndSetAsActive()
             }.map { TRUE }
     }
 
@@ -136,19 +152,50 @@ class UserManager internal constructor(private val userRepository: UsersReposito
         return userRepository.setUserAsActiveWithId(user.id!!)
     }
 
+    fun storeProfile(username: String?, userAttributes: UserAttributes): Maybe<User> {
+        val userMaybe: Maybe<User> = findUser(null, userAttributes)
+
+        return userMaybe
+            .map { user: User? ->
+                when (user) {
+                    null -> createUser(
+                        username,
+                        userAttributes
+                    )
+                    else -> {
+                        user.token = userAttributes.token
+                        user.baseUrl = userAttributes.serverUrl
+                        user.current = true
+                        user.userId = userAttributes.userId
+                        user.token = userAttributes.token
+                        user.displayName = userAttributes.displayName
+                        user.clientCertificate = userAttributes.certificateAlias
+
+                        updateUserData(
+                            user,
+                            userAttributes
+                        )
+
+                        user
+                    }
+                }
+            }
+            .switchIfEmpty(Maybe.just(createUser(username, userAttributes)))
+            .map { user ->
+                userRepository.insertUser(user)
+            }
+            .flatMap { id ->
+                userRepository.getUserWithId(id)
+            }
+    }
+
     @Deprecated("Only available for migration, use updateExternalSignalingServer or create new methods")
     fun createOrUpdateUser(
         username: String?,
         userAttributes: UserAttributes,
     ): Maybe<User> {
 
-        val userMaybe: Maybe<User> = if (userAttributes.id != null) {
-            userRepository.getUserWithId(userAttributes.id)
-        } else if (username != null && userAttributes.serverUrl != null) {
-            userRepository.getUserWithUsernameAndServer(username, userAttributes.serverUrl)
-        } else {
-            Maybe.empty()
-        }
+        val userMaybe: Maybe<User> = findUser(username, userAttributes)
 
         return userMaybe
             .map { user: User? ->
@@ -175,6 +222,16 @@ class UserManager internal constructor(private val userRepository: UsersReposito
             }
     }
 
+    private fun findUser(username: String?, userAttributes: UserAttributes): Maybe<User> {
+        return if (userAttributes.id != null) {
+            userRepository.getUserWithId(userAttributes.id)
+        } else if (username != null && userAttributes.serverUrl != null) {
+            userRepository.getUserWithUsernameAndServer(username, userAttributes.serverUrl)
+        } else {
+            Maybe.empty()
+        }
+    }
+
     fun getUserWithUsernameAndServer(username: String, server: String): Maybe<User> {
         return userRepository.getUserWithUsernameAndServer(username, server)
     }