From 12cb7e423bcb3cc8def9a41d3e4a9bb75738b6a9 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 29 Nov 2022 16:03:28 +0100 Subject: [PATCH] fix to move controllers to top add logging Signed-off-by: Marcel Hibbe --- .../nextcloud/talk/activities/MainActivity.kt | 39 ++++++++++---- .../talk/controllers/LockedController.kt | 13 +++++ .../talk/utils/ConductorRemapping.kt | 52 +++++++++++++------ .../nextcloud/talk/utils/SecurityUtils.java | 26 +++++++--- 4 files changed, 98 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt index e4a5ed9ed..9938c3dd5 100644 --- a/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/activities/MainActivity.kt @@ -37,6 +37,7 @@ import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.bluelinelabs.conductor.changehandler.VerticalChangeHandler import com.google.android.material.snackbar.Snackbar +import com.nextcloud.talk.BuildConfig import com.nextcloud.talk.R import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.application.NextcloudTalkApplication @@ -144,14 +145,13 @@ class MainActivity : BaseActivity(), ActionBarProvider { } override fun onStart() { - Log.d(TAG, "onStart: Activity: " + System.identityHashCode(this).toString()) - super.onStart() - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - checkIfWeAreSecure() - } + Log.d(TAG, "onStart: Activity: " + System.identityHashCode(this).toString()) + logRouterBackStack(router!!) - handleActionFromContact(intent) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + lockScreenIfConditionsApply() + } } override fun onResume() { @@ -324,7 +324,7 @@ class MainActivity : BaseActivity(), ActionBarProvider { } @RequiresApi(api = Build.VERSION_CODES.M) - fun checkIfWeAreSecure() { + fun lockScreenIfConditionsApply() { val keyguardManager = getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager if (keyguardManager.isKeyguardSecure && appPreferences.isScreenLocked) { if (!SecurityUtils.checkIfWeAreAuthenticated(appPreferences.screenLockTimeout)) { @@ -335,14 +335,15 @@ class MainActivity : BaseActivity(), ActionBarProvider { .popChangeHandler(VerticalChangeHandler()) .tag(LockedController.TAG) ) + logRouterBackStack(router!!) } } } } override fun onNewIntent(intent: Intent) { - Log.d(TAG, "onNewIntent Activity: " + System.identityHashCode(this).toString()) super.onNewIntent(intent) + Log.d(TAG, "onNewIntent Activity: " + System.identityHashCode(this).toString()) handleActionFromContact(intent) if (intent.hasExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) { if (intent.getBooleanExtra(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL, false)) { @@ -353,10 +354,16 @@ class MainActivity : BaseActivity(), ActionBarProvider { intent.extras?.let { callNotificationIntent.putExtras(it) } startActivity(callNotificationIntent) } else { + logRouterBackStack(router!!) remapChatController( - router!!, intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, - intent.getStringExtra(KEY_ROOM_TOKEN)!!, intent.extras!!, false, true + router!!, + intent.getParcelableExtra(KEY_USER_ENTITY)!!.id!!, + intent.getStringExtra(KEY_ROOM_TOKEN)!!, + intent.extras!!, + false, + true ) + logRouterBackStack(router!!) } } } @@ -371,6 +378,18 @@ class MainActivity : BaseActivity(), ActionBarProvider { } } + private fun logRouterBackStack(router: Router) { + if (BuildConfig.DEBUG) { + val backstack = router.backstack + var routerTransaction: RouterTransaction? + Log.d(TAG, " backstack size: " + router.backstackSize) + for (i in 0 until router.backstackSize) { + routerTransaction = backstack[i] + Log.d(TAG, " controller: " + routerTransaction.controller) + } + } + } + companion object { private const val TAG = "MainActivity" } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/LockedController.kt b/app/src/main/java/com/nextcloud/talk/controllers/LockedController.kt index 9b9276ed5..e18bdbbd6 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/LockedController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/LockedController.kt @@ -73,6 +73,7 @@ class LockedController : BaseController(R.layout.controller_locked) { @RequiresApi(api = Build.VERSION_CODES.M) override fun onAttach(view: View) { super.onAttach(view) + Log.d(TAG, "onAttach") if (activity != null && resources != null) { DisplayUtils.applyColorToStatusBar( activity, @@ -86,6 +87,11 @@ class LockedController : BaseController(R.layout.controller_locked) { checkIfWeAreSecure() } + override fun onDetach(view: View) { + super.onDetach(view) + Log.d(TAG, "onDetach") + } + @RequiresApi(api = Build.VERSION_CODES.M) fun unlock() { checkIfWeAreSecure() @@ -139,14 +145,21 @@ class LockedController : BaseController(R.layout.controller_locked) { val keyguardManager = activity?.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager? if (keyguardManager?.isKeyguardSecure == true && appPreferences!!.isScreenLocked) { if (!SecurityUtils.checkIfWeAreAuthenticated(appPreferences!!.screenLockTimeout)) { + Log.d(TAG, "showBiometricDialog because 'we are NOT authenticated'...") showBiometricDialog() } else { + Log.d( + TAG, + "popCurrentController because 'we are authenticated'. backstacksize= " + + router.backstack.size + ) router.popCurrentController() } } } private fun showAuthenticationScreen() { + Log.d(TAG, "showAuthenticationScreen") val keyguardManager = activity?.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager? val intent = keyguardManager?.createConfirmDeviceCredentialIntent(null, null) if (intent != null) { diff --git a/app/src/main/java/com/nextcloud/talk/utils/ConductorRemapping.kt b/app/src/main/java/com/nextcloud/talk/utils/ConductorRemapping.kt index 1f95bdca2..d8d7fb89c 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ConductorRemapping.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/ConductorRemapping.kt @@ -21,15 +21,19 @@ package com.nextcloud.talk.utils import android.os.Bundle +import android.util.Log import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler import com.nextcloud.talk.controllers.ChatController import com.nextcloud.talk.controllers.ConversationsListController +import com.nextcloud.talk.controllers.LockedController object ConductorRemapping { + private val TAG = ConductorRemapping::class.simpleName + fun remapChatController( router: Router, internalUserId: Long, @@ -48,20 +52,10 @@ object ConductorRemapping { replaceTop: Boolean, pushImmediately: Boolean ) { - val tag = "$internalUserId@$roomTokenOrId" - if (router.getControllerWithTag(tag) != null) { - val backstack = router.backstack - var routerTransaction: RouterTransaction? = null - for (i in 0 until router.backstackSize) { - if (tag == backstack[i].tag()) { - routerTransaction = backstack[i] - backstack.remove(routerTransaction) - break - } - } + val chatControllerTag = "$internalUserId@$roomTokenOrId" - backstack.add(routerTransaction) - router.setBackstack(backstack, HorizontalChangeHandler()) + if (router.getControllerWithTag(chatControllerTag) != null) { + moveControllerToTop(router, chatControllerTag) } else { val pushChangeHandler = if (pushImmediately) { SimpleSwapChangeHandler() @@ -70,29 +64,55 @@ object ConductorRemapping { } if (!replaceTop) { if (!router.hasRootController()) { + Log.d(TAG, "router has no RootController. creating backstack with ConversationsListController") val newBackstack = listOf( RouterTransaction.with(ConversationsListController(Bundle())) .pushChangeHandler(HorizontalChangeHandler()) .popChangeHandler(HorizontalChangeHandler()), RouterTransaction.with(ChatController(bundle)) .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()).tag(tag) + .popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) ) router.setBackstack(newBackstack, SimpleSwapChangeHandler()) } else { + Log.d(TAG, "router has RootController. pushing ChatController") router.pushController( RouterTransaction.with(ChatController(bundle)) .pushChangeHandler(pushChangeHandler) - .popChangeHandler(HorizontalChangeHandler()).tag(tag) + .popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) ) } } else { + Log.d(TAG, "ChatController replace topController") + router.replaceTopController( RouterTransaction.with(ChatController(bundle)) .pushChangeHandler(pushChangeHandler) - .popChangeHandler(HorizontalChangeHandler()).tag(tag) + .popChangeHandler(HorizontalChangeHandler()).tag(chatControllerTag) ) } } + + if (router.getControllerWithTag(LockedController.TAG) != null) { + moveControllerToTop(router, LockedController.TAG) + } + } + + private fun moveControllerToTop(router: Router, controllerTag: String) { + Log.d(TAG, "moving $controllerTag to top...") + val backstack = router.backstack + var routerTransaction: RouterTransaction? = null + for (i in 0 until router.backstackSize) { + if (controllerTag == backstack[i].tag()) { + routerTransaction = backstack[i] + backstack.remove(routerTransaction) + Log.d(TAG, "removed controller: " + routerTransaction.controller) + break + } + } + + backstack.add(routerTransaction) + Log.d(TAG, "added controller to top: " + routerTransaction!!.controller) + router.setBackstack(backstack, HorizontalChangeHandler()) } } diff --git a/app/src/main/java/com/nextcloud/talk/utils/SecurityUtils.java b/app/src/main/java/com/nextcloud/talk/utils/SecurityUtils.java index 2542086d6..5420f44af 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/SecurityUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/SecurityUtils.java @@ -27,18 +27,32 @@ import android.security.keystore.KeyPermanentlyInvalidatedException; import android.security.keystore.KeyProperties; import android.security.keystore.UserNotAuthenticatedException; import android.util.Log; -import androidx.annotation.RequiresApi; -import androidx.biometric.BiometricPrompt; + import com.nextcloud.talk.R; import com.nextcloud.talk.application.NextcloudTalkApplication; -import javax.crypto.*; import java.io.IOException; -import java.security.*; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Arrays; import java.util.List; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; + +import androidx.annotation.RequiresApi; +import androidx.biometric.BiometricPrompt; + public class SecurityUtils { private static final String TAG = "SecurityUtils"; private static final String CREDENTIALS_KEY = "KEY_CREDENTIALS"; @@ -68,8 +82,8 @@ public class SecurityUtils { return false; } catch (KeyPermanentlyInvalidatedException e) { // This happens if the lock screen has been disabled or reset after the key was - // generated after the key was generated. - // Shouldnt really happen because we regenerate the key every time an activity + // generated. + // Shouldn't really happen because we regenerate the key every time an activity // is created, but oh well // Create key, and attempt again createKey(screenLockTimeout);