Skip to content

Commit a27b22f

Browse files
MHShettythestinger
authored andcommitted
Auto finish secure activities when the screen goes off
(and the user is inactive for a certain short duration)
1 parent 37990f8 commit a27b22f

File tree

5 files changed

+109
-2
lines changed

5 files changed

+109
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package app.grapheneos.camera
2+
3+
import android.app.Activity
4+
import android.content.BroadcastReceiver
5+
import android.content.Context
6+
import android.content.Intent
7+
import android.content.IntentFilter
8+
import android.os.Handler
9+
import android.os.Looper
10+
import androidx.core.app.ActivityCompat
11+
12+
// Finishes the passed [activity] and the ones present below it in the stack if the screen
13+
// turns off and the user is inactive for [WAITING_TIME_IN_MS] milliseconds
14+
class AutoFinishOnSleep(val activity: Activity) {
15+
16+
companion object {
17+
private const val TAG = "AutoFinishOnSleep"
18+
private const val WAITING_TIME_IN_MS = 1500L
19+
20+
private val intentFilter = IntentFilter().apply {
21+
addAction(Intent.ACTION_SCREEN_ON)
22+
addAction(Intent.ACTION_SCREEN_OFF)
23+
}
24+
}
25+
26+
private val handler = Handler(Looper.getMainLooper())
27+
28+
private val runnable = Runnable {
29+
ActivityCompat.finishAffinity(activity)
30+
}
31+
32+
private val receiver = object: BroadcastReceiver() {
33+
override fun onReceive(context: Context?, intent: Intent?) {
34+
when(intent?.action) {
35+
Intent.ACTION_SCREEN_OFF -> {
36+
handler.postDelayed(runnable, WAITING_TIME_IN_MS)
37+
}
38+
39+
Intent.ACTION_SCREEN_ON -> {
40+
handler.removeCallbacks(runnable)
41+
}
42+
}
43+
}
44+
}
45+
46+
fun start() {
47+
activity.registerReceiver(receiver, intentFilter)
48+
}
49+
50+
fun stop() {
51+
activity.unregisterReceiver(receiver)
52+
}
53+
}

app/src/main/java/app/grapheneos/camera/ui/activities/InAppGallery.kt

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import androidx.core.view.WindowInsetsCompat
3434
import androidx.core.view.WindowInsetsControllerCompat
3535
import androidx.viewpager2.widget.ViewPager2
3636
import androidxc.exifinterface.media.ExifInterface
37+
import app.grapheneos.camera.AutoFinishOnSleep
3738
import app.grapheneos.camera.CapturedItem
3839
import app.grapheneos.camera.CapturedItems
3940
import app.grapheneos.camera.GSlideTransformer
@@ -70,6 +71,8 @@ class InAppGallery : AppCompatActivity() {
7071

7172
private lateinit var rootView: View
7273

74+
private val autoFinisher = AutoFinishOnSleep(this)
75+
7376
private var lastViewedMediaItem : CapturedItem? = null
7477

7578
private lateinit var windowInsetsController: WindowInsetsControllerCompat
@@ -446,6 +449,7 @@ class InAppGallery : AppCompatActivity() {
446449
if (isSecureMode) {
447450
setShowWhenLocked(true)
448451
setTurnScreenOn(true)
452+
autoFinisher.start()
449453
}
450454

451455
ogColor = ContextCompat.getColor(this, R.color.system_neutral1_900)
@@ -637,6 +641,9 @@ class InAppGallery : AppCompatActivity() {
637641
super.onDestroy()
638642
asyncLoaderOfCapturedItems.shutdownNow()
639643
asyncImageLoader.shutdownNow()
644+
if (isSecureMode) {
645+
autoFinisher.stop()
646+
}
640647
}
641648

642649
fun vibrateDevice() {
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
11
package app.grapheneos.camera.ui.activities
22

3-
class MoreSettingsSecure : MoreSettings()
3+
import android.os.Bundle
4+
import app.grapheneos.camera.AutoFinishOnSleep
5+
6+
class MoreSettingsSecure : MoreSettings() {
7+
8+
private val autoFinisher = AutoFinishOnSleep(this)
9+
10+
override fun onCreate(savedInstanceState: Bundle?) {
11+
super.onCreate(savedInstanceState)
12+
autoFinisher.start()
13+
}
14+
15+
override fun onDestroy() {
16+
super.onDestroy()
17+
autoFinisher.stop()
18+
}
19+
}

app/src/main/java/app/grapheneos/camera/ui/activities/SecureMainActivity.kt

+14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package app.grapheneos.camera.ui.activities
22

33
import android.content.SharedPreferences
4+
import android.os.Bundle
5+
import app.grapheneos.camera.AutoFinishOnSleep
46
import app.grapheneos.camera.CapturedItem
57
import app.grapheneos.camera.util.EphemeralSharedPrefsNamespace
68
import app.grapheneos.camera.util.getPrefs
@@ -9,6 +11,18 @@ open class SecureMainActivity : MainActivity(), SecureActivity {
911
val capturedItems = ArrayList<CapturedItem>()
1012
val ephemeralPrefsNamespace = EphemeralSharedPrefsNamespace()
1113

14+
private val autoFinisher = AutoFinishOnSleep(this)
15+
16+
override fun onCreate(savedInstanceState: Bundle?) {
17+
super.onCreate(savedInstanceState)
18+
autoFinisher.start()
19+
}
20+
21+
override fun onDestroy() {
22+
super.onDestroy()
23+
autoFinisher.stop()
24+
}
25+
1226
override fun getSharedPreferences(name: String, mode: Int): SharedPreferences {
1327
return ephemeralPrefsNamespace.getPrefs(this, name, mode, cloneOriginal = true)
1428
}

app/src/main/java/app/grapheneos/camera/ui/activities/VideoPlayer.kt

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import androidx.core.view.ViewCompat
1616
import androidx.core.view.WindowCompat
1717
import androidx.core.view.WindowInsetsCompat
1818
import androidx.lifecycle.Lifecycle
19+
import app.grapheneos.camera.AutoFinishOnSleep
1920
import app.grapheneos.camera.R
2021
import app.grapheneos.camera.databinding.VideoPlayerBinding
2122
import app.grapheneos.camera.util.getParcelableExtra
@@ -32,6 +33,10 @@ class VideoPlayer : AppCompatActivity() {
3233

3334
private lateinit var binding: VideoPlayerBinding
3435

36+
private val autoFinisher = AutoFinishOnSleep(this)
37+
38+
private var isSecureMode = false
39+
3540
override fun onCreate(savedInstanceState: Bundle?) {
3641
super.onCreate(savedInstanceState)
3742
enableEdgeToEdge()
@@ -42,10 +47,15 @@ class VideoPlayer : AppCompatActivity() {
4247
windowInsetsController.show(WindowInsetsCompat.Type.systemBars())
4348

4449
val intent = this.intent
45-
if (intent.getBooleanExtra(IN_SECURE_MODE, false)) {
50+
51+
isSecureMode = intent.getBooleanExtra(IN_SECURE_MODE, false)
52+
53+
if (isSecureMode) {
4654
setShowWhenLocked(true)
4755
setTurnScreenOn(true)
56+
autoFinisher.start()
4857
}
58+
4959
binding = VideoPlayerBinding.inflate(layoutInflater)
5060
setContentView(binding.root)
5161

@@ -165,4 +175,11 @@ class VideoPlayer : AppCompatActivity() {
165175
alpha(1f)
166176
}
167177
}
178+
179+
override fun onDestroy() {
180+
super.onDestroy()
181+
if (isSecureMode) {
182+
this.autoFinisher.stop()
183+
}
184+
}
168185
}

0 commit comments

Comments
 (0)