Skip to content

Commit 2062044

Browse files
Updated freeRASP API with new screen capture protection methods (#53)
* Updated with new APIs: onScreenshotDetected, onScreenRecordingDetected, blockScreenCapture * Increased version --------- Co-authored-by: Matúš Šikyňa <118438675+msikyna@users.noreply.github.com>
1 parent 8f5f7fc commit 2062044

File tree

6 files changed

+94
-10
lines changed

6 files changed

+94
-10
lines changed

FreeRASPDemoApp/app/build.gradle

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ android {
77
defaultConfig {
88
applicationId "com.aheaditec.talsec.demoapp"
99
minSdk 23
10-
compileSdk 34
11-
targetSdk 34
10+
compileSdk 35
11+
targetSdk 35
1212
versionCode 1
1313
versionName "1.0"
1414

@@ -30,11 +30,13 @@ android {
3030
kotlinOptions {
3131
jvmTarget = '1.8'
3232
}
33+
34+
namespace "com.aheaditec.talsec.demoapp"
3335
}
3436

3537
dependencies {
3638
// freeRASP SDK
37-
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community:13.2.0'
39+
implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community:14.0.1'
3840

3941
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
4042
implementation 'androidx.core:core-ktx:1.12.0'

FreeRASPDemoApp/app/src/main/AndroidManifest.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
33
package="com.aheaditec.talsec.demoapp">
44

5+
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
6+
<uses-permission android:name="android.permission.DETECT_SCREEN_RECORDING" />
7+
58
<application
69
android:name=".TalsecApplication"
710
android:allowBackup="true"

FreeRASPDemoApp/app/src/main/java/com/aheaditec/talsec/demoapp/TalsecApplication.kt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
package com.aheaditec.talsec.demoapp
22

3+
import android.app.Activity
34
import android.app.Application
5+
import android.os.Build
6+
import android.os.Bundle
47
import android.util.Log
8+
import android.view.WindowManager.SCREEN_RECORDING_STATE_VISIBLE
59
import com.aheaditec.talsec_security.security.api.SuspiciousAppInfo
610
import com.aheaditec.talsec_security.security.api.Talsec
711
import com.aheaditec.talsec_security.security.api.TalsecConfig
812
import com.aheaditec.talsec_security.security.api.ThreatListener
13+
import java.util.function.Consumer
914

1015
class TalsecApplication : Application(), ThreatListener.ThreatDetected {
1116

17+
private var currentActivity: Activity? = null
18+
private var screenCaptureCallback: Activity.ScreenCaptureCallback? = null
19+
private val screenRecordCallback: Consumer<Int> = Consumer<Int> { state ->
20+
if (state == SCREEN_RECORDING_STATE_VISIBLE) {
21+
Talsec.onScreenRecordingDetected()
22+
}
23+
}
24+
1225
override fun onCreate() {
1326
super.onCreate()
1427

@@ -26,6 +39,64 @@ class TalsecApplication : Application(), ThreatListener.ThreatDetected {
2639

2740
ThreatListener(this, deviceStateListener).registerListener(this)
2841
Talsec.start(this, config)
42+
43+
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
44+
override fun onActivityCreated(activity: Activity, bundle: Bundle?) {
45+
46+
// Set to 'true' to block screen capture
47+
Talsec.blockScreenCapture(activity, false)
48+
}
49+
50+
override fun onActivityStarted(activity: Activity) {
51+
unregisterCallbacks()
52+
currentActivity = activity
53+
registerCallbacks(activity)
54+
}
55+
56+
override fun onActivityResumed(activity: Activity) {}
57+
override fun onActivityPaused(activity: Activity) {}
58+
59+
override fun onActivityStopped(activity: Activity) {
60+
if (activity == currentActivity) {
61+
unregisterCallbacks()
62+
currentActivity = null
63+
}
64+
}
65+
66+
override fun onActivitySaveInstanceState(activity: Activity, bundle: Bundle) {}
67+
override fun onActivityDestroyed(activity: Activity) {}
68+
})
69+
}
70+
71+
private fun registerCallbacks(activity: Activity) {
72+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
73+
screenCaptureCallback = Activity.ScreenCaptureCallback {
74+
Talsec.onScreenshotDetected()
75+
}
76+
activity.registerScreenCaptureCallback(
77+
baseContext.mainExecutor, screenCaptureCallback!!
78+
)
79+
}
80+
81+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
82+
val initialState = activity.windowManager.addScreenRecordingCallback(
83+
mainExecutor, screenRecordCallback
84+
)
85+
screenRecordCallback.accept(initialState)
86+
}
87+
}
88+
89+
private fun unregisterCallbacks() {
90+
currentActivity?.let { activity ->
91+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && screenCaptureCallback != null) {
92+
activity.unregisterScreenCaptureCallback(screenCaptureCallback!!)
93+
screenCaptureCallback = null
94+
}
95+
96+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
97+
activity.windowManager.removeScreenRecordingCallback(screenRecordCallback)
98+
}
99+
}
29100
}
30101

31102
override fun onRootDetected() {
@@ -77,6 +148,14 @@ class TalsecApplication : Application(), ThreatListener.ThreatDetected {
77148
println("onMalwareDetected")
78149
}
79150

151+
override fun onScreenshotDetected() {
152+
println("onScreenshotDetected")
153+
}
154+
155+
override fun onScreenRecordingDetected() {
156+
println("onScreenRecordingDetected")
157+
}
158+
80159
// This is optional. Use only if you are interested in device state information like device lock and HW backed keystore state
81160
private val deviceStateListener = object : ThreatListener.DeviceState {
82161
override fun onUnlockedDeviceDetected() {

FreeRASPDemoApp/app/src/main/java/com/aheaditec/talsec/demoapp/Utils.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,23 @@ object Utils {
3030
private fun getApkSigningCertificate(packageInfo: PackageInfo): List<String> {
3131
val signingHashes = mutableListOf<String>()
3232
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
33-
packageInfo.signingInfo.apply {
33+
packageInfo.signingInfo?.apply {
3434
if (hasMultipleSigners()) {
35-
apkContentsSigners.forEach {
35+
apkContentsSigners?.forEach {
3636
signingHashes.add(
3737
hashCertificate(it)
3838
)
3939
}
4040
} else {
41-
signingCertificateHistory.forEach {
41+
signingCertificateHistory?.forEach {
4242
signingHashes.add(
4343
hashCertificate(it)
4444
)
4545
}
4646
}
4747
}
4848
} else {
49-
packageInfo.signatures.forEach {
49+
packageInfo.signatures?.forEach {
5050
signingHashes.add(
5151
hashCertificate(it)
5252
)

FreeRASPDemoApp/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
buildscript {
3-
ext.kotlin_version = "1.7.10"
3+
ext.kotlin_version = "2.0.0"
44
repositories {
55
google()
66
mavenCentral()
77
}
88
dependencies {
9-
classpath "com.android.tools.build:gradle:7.1.3"
9+
classpath "com.android.tools.build:gradle:8.7.3"
1010
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
1111

1212
// NOTE: Do not place your application dependencies here; they belong
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)