Skip to content

Commit d79fad9

Browse files
authored
Merge pull request #74 from akaMrNagar/dev
Fix: Multiple overlays makes device unresponsive
2 parents 009b698 + 01e17b2 commit d79fad9

File tree

9 files changed

+50
-61
lines changed

9 files changed

+50
-61
lines changed

android/app/src/main/java/com/mindful/android/receivers/DeviceLockUnlockReceiver.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ class DeviceLockUnlockReceiver(
3333
override fun onReceive(context: Context, intent: Intent) {
3434
when (intent.action) {
3535
Intent.ACTION_USER_PRESENT -> {
36-
onDeviceLockChanged.invoke(true)
3736
Log.d(TAG, "onDeviceUnlocked: User UNLOCKED the device and device is ACTIVE")
37+
onDeviceLockChanged.invoke(true)
3838
}
3939

4040
Intent.ACTION_SCREEN_OFF -> {
41-
onDeviceLockChanged.invoke(false)
4241
Log.d(TAG, "onDeviceLocked: User LOCKED the device and device is INACTIVE")
42+
onDeviceLockChanged.invoke(false)
4343
}
4444
}
4545
}

android/app/src/main/java/com/mindful/android/services/accessibility/MindfulAccessibilityService.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import com.mindful.android.helpers.device.PermissionsHelper
2828
import com.mindful.android.helpers.storage.SharedPrefsHelper
2929
import com.mindful.android.models.WellBeingSettings
3030
import com.mindful.android.receivers.DeviceAppsChangedReceiver
31-
import com.mindful.android.receivers.alarm.MidnightResetReceiver
3231
import com.mindful.android.utils.AppConstants.FACEBOOK_PACKAGE
3332
import com.mindful.android.utils.AppConstants.INSTAGRAM_PACKAGE
3433
import com.mindful.android.utils.AppConstants.REDDIT_PACKAGE

android/app/src/main/java/com/mindful/android/services/accessibility/TrackingManager.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,9 @@ class TrackingManager(
2727

2828
@WorkerThread
2929
fun onNewEvent(packageName: String) {
30-
if (lastActiveApp != packageName) {
30+
if (lastActiveApp != packageName && !ignoredPackages.contains(packageName)) {
3131
lastActiveApp = packageName
32-
33-
// only send broadcast if packages are not ignored
34-
if (!ignoredPackages.contains(packageName)) {
35-
broadcastEvent(ACTION_NEW_APP_LAUNCHED)
36-
}
32+
broadcastEvent(ACTION_NEW_APP_LAUNCHED)
3733
}
3834
}
3935

android/app/src/main/java/com/mindful/android/services/tracking/LaunchTrackingManager.kt

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.mindful.android.services.tracking
22

3-
import android.accessibilityservice.AccessibilityService
43
import android.app.Service.USAGE_STATS_SERVICE
54
import android.app.usage.UsageEvents
65
import android.app.usage.UsageStatsManager
@@ -13,6 +12,7 @@ import android.util.Log
1312
import androidx.annotation.MainThread
1413
import androidx.annotation.WorkerThread
1514
import com.mindful.android.receivers.DeviceLockUnlockReceiver
15+
import com.mindful.android.services.accessibility.MindfulAccessibilityService
1616
import com.mindful.android.services.accessibility.TrackingManager.Companion.ACTION_NEW_APP_LAUNCHED
1717
import com.mindful.android.services.accessibility.TrackingManager.Companion.ACTION_START_MANUAL_TRACKING
1818
import com.mindful.android.services.accessibility.TrackingManager.Companion.ACTION_STOP_MANUAL_TRACKING
@@ -75,8 +75,6 @@ class LaunchTrackingManager(
7575
context.registerReceiver(accessibilityReceiver, accessibilityFilter)
7676
}
7777

78-
// Check if accessibility is already running
79-
isManualTrackingOn = !Utils.isServiceRunning(context, AccessibilityService::class.java)
8078

8179
// Start tracking
8280
onDeviceUnlocked()
@@ -85,6 +83,10 @@ class LaunchTrackingManager(
8583

8684
@MainThread
8785
private fun onDeviceUnlocked() {
86+
// Check if accessibility is already running
87+
isManualTrackingOn =
88+
!Utils.isServiceRunning(context, MindfulAccessibilityService::class.java)
89+
8890
// Start tracking manually only if accessibility is not running
8991
if (isManualTrackingOn) {
9092
// First cancel earlier task if already not cancelled
@@ -100,15 +102,18 @@ class LaunchTrackingManager(
100102
)
101103

102104
Log.d(TAG, "onDeviceUnlocked: Manual usage tracking started")
103-
Thread { broadcastLastAppLaunchEvent() }.start()
104105
}
106+
107+
Thread { broadcastLastAppLaunchEvent() }.start()
105108
}
106109

107110
@MainThread
108111
private fun onDeviceLocked() {
109112
trackingExecutor?.shutdownNow()
110113
trackingExecutor = null
111114

115+
// To cancel reminders and remove overlay
116+
onNewAppLaunched.invoke("com.android.systemui")
112117
Log.d(TAG, "onDeviceLocked: Manual usage tracking stopped")
113118
}
114119

@@ -200,7 +205,10 @@ class LaunchTrackingManager(
200205

201206
ACTION_NEW_APP_LAUNCHED -> intent.getStringExtra(AppConstants.INTENT_EXTRA_PACKAGE_NAME)
202207
?.let {
203-
Thread { onNewAppLaunched.invoke(it) }.start()
208+
Thread {
209+
lastLaunchedApp = it
210+
broadcastLastAppLaunchEvent()
211+
}.start()
204212
}
205213

206214
}

android/app/src/main/java/com/mindful/android/services/tracking/MindfulTrackerService.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,21 @@ class MindfulTrackerService : Service() {
6464

6565
fun onMidnightReset() {
6666
restrictionManager.resetCache()
67-
overlayManager.dismissOverlay()
67+
// overlayManager.dismissOverlay()
6868
// reminderManager.cancelReminders()
6969
}
7070

7171

7272
@WorkerThread
7373
private fun onNewAppLaunch(packageName: String) {
7474
try {
75-
Log.d(TAG, "onNewAppLaunch: $packageName launched")
7675

7776
/// Cancel previous reminders and dismiss overlay
7877
reminderManager.cancelReminders()
7978
overlayManager.dismissOverlay()
8079

8180
/// check current restrictions
82-
val currentOrFutureState = restrictionManager.isAppRestricted(packageName)
81+
val currentOrFutureState = restrictionManager.isAppRestricted(packageName)
8382

8483
Log.d(TAG, "onNewAppLaunch: $packageName's evaluated state $currentOrFutureState")
8584
currentOrFutureState?.let {

android/app/src/main/java/com/mindful/android/services/tracking/OverlayBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import android.widget.ProgressBar
1313
import android.widget.TextView
1414
import androidx.annotation.MainThread
1515
import com.mindful.android.R
16-
import com.mindful.android.models.RestrictionState
1716
import com.mindful.android.enums.RestrictionType
17+
import com.mindful.android.models.RestrictionState
1818
import com.mindful.android.utils.ThreadUtils
1919
import com.mindful.android.utils.Utils
2020

android/app/src/main/java/com/mindful/android/services/tracking/OverlayManager.kt

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,23 @@ import com.mindful.android.R
1818
import com.mindful.android.helpers.device.NotificationHelper
1919
import com.mindful.android.models.RestrictionState
2020
import com.mindful.android.utils.ThreadUtils
21+
import java.util.Stack
2122

2223
class OverlayManager(
2324
private val context: Context,
2425
) {
2526
private val windowManager: WindowManager =
2627
context.getSystemService(WINDOW_SERVICE) as WindowManager
2728

28-
private var overlay: View? = null
29-
private var isDismissingOverlay: Boolean = false
29+
private var overlays: Stack<View> = Stack()
30+
3031

3132
init {
3233
fadeOutAnim.setAnimationListener(
3334
object : Animation.AnimationListener {
34-
override fun onAnimationStart(a: Animation?) {
35-
isDismissingOverlay = true
36-
}
37-
35+
override fun onAnimationStart(a: Animation?) {}
3836
override fun onAnimationRepeat(a: Animation?) {}
39-
4037
override fun onAnimationEnd(a: Animation?) {
41-
isDismissingOverlay = false
4238
removeOverlay()
4339
}
4440
}
@@ -47,22 +43,16 @@ class OverlayManager(
4743

4844
/// Animate out the overlay
4945
fun dismissOverlay() {
50-
/// Skip if already animating to dismiss
51-
if (isDismissingOverlay) {
52-
return
53-
}
54-
46+
if (overlays.isEmpty()) return
5547
ThreadUtils.runOnMainThread {
56-
animateOverlay(animateIn = false)
48+
animateOverlay(overlay = overlays.peek(), animateIn = false)
5749
}
5850
}
5951

60-
/// Remove overlay after animating out
52+
/// Remove overlay instantly
6153
private fun removeOverlay() {
62-
overlay?.let {
63-
windowManager.removeView(it)
64-
overlay = null
65-
}
54+
if (overlays.isEmpty()) return
55+
windowManager.removeView(overlays.pop())
6656
}
6757

6858

@@ -71,8 +61,10 @@ class OverlayManager(
7161
restrictionState: RestrictionState,
7262
addReminderDelay: ((futureMinutes: Int) -> Unit)? = null,
7363
) {
74-
Log.d(TAG, "showOverlay: Showing overlay for $packageName")
64+
// Return if overlay is not null
65+
if (overlays.isNotEmpty()) return
7566

67+
Log.d(TAG, "showOverlay: Showing overlay for $packageName")
7668
ThreadUtils.runOnMainThread {
7769
// Notify, stop and return if don't have overlay permission
7870
if (!Settings.canDrawOverlays(context)) {
@@ -85,7 +77,7 @@ class OverlayManager(
8577
}
8678

8779
// Build overlay
88-
overlay = OverlayBuilder.buildOverlay(
80+
val overlay = OverlayBuilder.buildOverlay(
8981
context,
9082
packageName,
9183
restrictionState,
@@ -111,24 +103,23 @@ class OverlayManager(
111103

112104
// TODO: Fix the deprecated logic
113105
// Full screen edge to edge view
114-
overlay?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
106+
overlay.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
115107
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
116108
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
117109

118110

119111
// Add the overlay view to the window
120112
layoutParams.gravity = Gravity.TOP or Gravity.START
121113
windowManager.addView(overlay, layoutParams)
122-
overlay?.rotation = 0f
123-
overlay?.findViewById<FrameLayout>(R.id.overlay_root)?.rotation = 0f
114+
overlays.push(overlay)
124115

125116
// Animate the overlay
126-
animateOverlay(animateIn = true)
117+
animateOverlay(overlay = overlay, animateIn = true)
127118
}
128119
}
129120

130-
private fun animateOverlay(animateIn: Boolean) {
131-
overlay?.let { view ->
121+
private fun animateOverlay(overlay: View, animateIn: Boolean) {
122+
overlay.let { view ->
132123
// Find the layers within overlay view
133124
val bgLayer = view.findViewById<View>(R.id.overlay_background)
134125
val sheetLayer = view.findViewById<LinearLayout>(R.id.overlay_sheet)

android/app/src/main/java/com/mindful/android/services/tracking/ReminderManager.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ class ReminderManager(
3030
state: RestrictionState,
3131
) {
3232
// If it is a timer restricted state
33-
if (state.usedScreenTime > 0
34-
&& state.totalScreenTimer > 0
35-
&& ((state.totalScreenTimer - state.usedScreenTime) > 120)
36-
) {
33+
if ((state.totalScreenTimer - state.usedScreenTime) > 120) {
3734
reminderTriggers.add(1)
3835
}
3936

@@ -48,10 +45,9 @@ class ReminderManager(
4845

4946
Log.d(
5047
TAG,
51-
"onTick: $spentMins Minute ticked with reminders: $reminderTriggers"
48+
"onTick: Elapsed $spentMins minutes with reminders: $reminderTriggers"
5249
)
5350

54-
5551
if (reminderTriggers.contains(spentMins)) {
5652
reminderTriggers.remove(spentMins)
5753
overlayManager.showOverlay(

android/app/src/main/java/com/mindful/android/services/tracking/RestrictionManager.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,30 +205,30 @@ class RestrictionManager(
205205

206206
/// Check for app timer
207207
if (restriction.timerSec > 0) {
208-
val screenTime: Long = screenUsage[restriction.appPackage] ?: 0
208+
val screenTimeSec: Long = screenUsage[restriction.appPackage] ?: 0
209209

210210
/// App timer ran out
211-
if (screenTime >= restriction.timerSec) {
211+
if (screenTimeSec >= restriction.timerSec) {
212212
Log.d(TAG, "evaluateScreenTimeLimit: App's timer is over")
213213
val state = RestrictionState(
214214
message = context.getString(R.string.app_paused_reason_app_timer_out),
215215
type = RestrictionType.Timer,
216216
expirationFutureMs = -1L,
217-
usedScreenTime = screenTime,
217+
usedScreenTime = screenTimeSec,
218218
totalScreenTimer = restriction.timerSec.toLong(),
219219
)
220220

221221
alreadyRestrictedApps[restriction.appPackage] = state
222222
return state
223223
} else {
224224
/// App timer left so add expiration timestamp
225-
val leftAppLimitMs = (restriction.timerSec - screenTime) * 1000L
225+
val leftAppLimitMs = (restriction.timerSec - screenTimeSec) * 1000L
226226
futureStates.add(
227227
RestrictionState(
228228
message = context.getString(R.string.app_paused_reason_app_timer_left),
229229
type = RestrictionType.Timer,
230230
expirationFutureMs = leftAppLimitMs,
231-
usedScreenTime = screenTime,
231+
usedScreenTime = screenTimeSec,
232232
totalScreenTimer = restriction.timerSec.toLong(),
233233
)
234234
)
@@ -244,10 +244,10 @@ class RestrictionManager(
244244
}
245245

246246
if (group.timerSec > 0) {
247-
val groupScreenTime = group.distractingApps.sumOf { screenUsage[it] ?: 0 }
247+
val groupScreenTimeSec = group.distractingApps.sumOf { screenUsage[it] ?: 0 }
248248

249249
/// group timer ran out
250-
if (groupScreenTime >= group.timerSec) {
250+
if (groupScreenTimeSec >= group.timerSec) {
251251
Log.d(TAG, "evaluateScreenTimeLimit: App's timer is over")
252252
val state = RestrictionState(
253253
message = context.getString(
@@ -256,15 +256,15 @@ class RestrictionManager(
256256
),
257257
type = RestrictionType.Timer,
258258
expirationFutureMs = -1L,
259-
usedScreenTime = groupScreenTime,
259+
usedScreenTime = groupScreenTimeSec,
260260
totalScreenTimer = group.timerSec.toLong(),
261261
)
262262

263263
alreadyRestrictedGroups[group.id] = state
264264
return state
265265
} else {
266266
/// group timer left so add expiration timestamp
267-
val leftAppLimitMs = (group.timerSec - groupScreenTime) * 1000L
267+
val leftAppLimitMs = (group.timerSec - groupScreenTimeSec) * 1000L
268268
futureStates.add(
269269
RestrictionState(
270270
message = context.getString(
@@ -273,7 +273,7 @@ class RestrictionManager(
273273
),
274274
type = RestrictionType.Timer,
275275
expirationFutureMs = leftAppLimitMs,
276-
usedScreenTime = groupScreenTime,
276+
usedScreenTime = groupScreenTimeSec,
277277
totalScreenTimer = group.timerSec.toLong(),
278278
)
279279
)

0 commit comments

Comments
 (0)