@@ -25,6 +25,7 @@ import android.content.Intent
2525import android.os.PowerManager
2626import android.view.View
2727import android.view.WindowManager
28+ import androidx.annotation.VisibleForTesting
2829import com.nextcloud.client.core.Clock
2930import com.nextcloud.client.preferences.AppPreferences
3031import com.owncloud.android.MainApp
@@ -48,9 +49,12 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
4849 * the pass code being requested on screen rotations.
4950 */
5051 private const val PASS_CODE_TIMEOUT = 5000
52+
53+ private const val TAG = " PassCodeManager"
5154 }
5255
5356 private var visibleActivitiesCounter = 0
57+ private var lastResumedActivity: Activity ? = null
5458
5559 private fun isExemptActivity (activity : Activity ): Boolean {
5660 return exemptOfPasscodeActivities.contains(activity.javaClass)
@@ -64,20 +68,17 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
6468 if (! isExemptActivity(activity)) {
6569 val passcodeRequested = passCodeShouldBeRequested(timestamp)
6670 val credentialsRequested = deviceCredentialsShouldBeRequested(timestamp, activity)
67- if (passcodeRequested || credentialsRequested) {
68- getActivityRootView(activity)?.visibility = View .GONE
69- } else {
70- getActivityRootView(activity)?.visibility = View .VISIBLE
71- }
71+ val shouldHideView = passcodeRequested || credentialsRequested
72+ toggleActivityVisibility(shouldHideView, activity)
73+ askedForPin = shouldHideView
74+
7275 if (passcodeRequested) {
73- askedForPin = true
74- preferences.lockTimestamp = 0
7576 requestPasscode(activity)
77+ } else if (credentialsRequested) {
78+ requestCredentials(activity)
7679 }
77- if (credentialsRequested) {
78- askedForPin = true
80+ if (askedForPin) {
7981 preferences.lockTimestamp = 0
80- requestCredentials(activity)
8182 }
8283 }
8384
@@ -86,12 +87,39 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
8687 }
8788
8889 if (! isExemptActivity(activity)) {
89- visibleActivitiesCounter ++ // keep it AFTER passCodeShouldBeRequested was checked
90+ addVisibleActivity(activity) // keep it AFTER passCodeShouldBeRequested was checked
9091 }
9192
9293 return askedForPin
9394 }
9495
96+ /* *
97+ * Used to hide root view while transitioning to passcode activity
98+ */
99+ private fun toggleActivityVisibility (
100+ hide : Boolean ,
101+ activity : Activity
102+ ) {
103+ if (hide) {
104+ getActivityRootView(activity)?.visibility = View .GONE
105+ } else {
106+ getActivityRootView(activity)?.visibility = View .VISIBLE
107+ }
108+ }
109+
110+ private fun addVisibleActivity (activity : Activity ) {
111+ // don't count the same activity twice
112+ if (lastResumedActivity != activity) {
113+ visibleActivitiesCounter++
114+ lastResumedActivity = activity
115+ }
116+ }
117+
118+ private fun removeVisibleActivity () {
119+ visibleActivitiesCounter--
120+ lastResumedActivity = null
121+ }
122+
95123 private fun setSecureFlag (activity : Activity ) {
96124 val window = activity.window
97125 if (window != null ) {
@@ -118,10 +146,10 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
118146
119147 fun onActivityStopped (activity : Activity ) {
120148 if (visibleActivitiesCounter > 0 && ! isExemptActivity(activity)) {
121- visibleActivitiesCounter --
149+ removeVisibleActivity()
122150 }
123151 val powerMgr = activity.getSystemService(Context .POWER_SERVICE ) as PowerManager
124- if ((isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) && ! powerMgr? .isScreenOn) {
152+ if ((isPassCodeEnabled() || deviceCredentialsAreEnabled(activity)) && ! powerMgr.isScreenOn) {
125153 activity.moveTaskToBack(true )
126154 }
127155 }
@@ -137,7 +165,8 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
137165 abs(clock.millisSinceBoot - timestamp) > PASS_CODE_TIMEOUT &&
138166 visibleActivitiesCounter <= 0
139167
140- private fun passCodeShouldBeRequested (timestamp : Long ): Boolean {
168+ @VisibleForTesting
169+ fun passCodeShouldBeRequested (timestamp : Long ): Boolean {
141170 return shouldBeLocked(timestamp) && isPassCodeEnabled()
142171 }
143172
@@ -153,7 +182,7 @@ class PassCodeManager(private val preferences: AppPreferences, private val clock
153182 }
154183
155184 private fun getActivityRootView (activity : Activity ): View ? {
156- return activity.window.findViewById(android.R .id.content)
157- ? : activity.window.decorView.findViewById(android.R .id.content)
185+ return activity.window? .findViewById(android.R .id.content)
186+ ? : activity.window? .decorView? .findViewById(android.R .id.content)
158187 }
159188}
0 commit comments