Skip to content

Commit

Permalink
fix max failed password attempts not showing on Android before Q
Browse files Browse the repository at this point in the history
  • Loading branch information
lucky committed Jun 11, 2022
1 parent c9ad201 commit 4812468
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 43 deletions.
12 changes: 6 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ android {
applicationId "me.lucky.sentry"
minSdk 23
targetSdk 32
versionCode 2
versionName "1.0.1"
versionCode 3
versionName "1.0.2"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -39,10 +39,10 @@ android {
}

dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/me/lucky/sentry/DeviceAdminReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ class DeviceAdminReceiver : DeviceAdminReceiver() {
super.onPasswordFailed(context, intent, user)
val prefs = Preferences(context)
val maxFailedPasswordAttempts = prefs.maxFailedPasswordAttempts
if (!prefs.isServiceEnabled || maxFailedPasswordAttempts <= 0) return
if (!prefs.isEnabled || maxFailedPasswordAttempts <= 0) return
val admin = DeviceAdminManager(context)
if (admin.getCurrentFailedPasswordAttempts() >= maxFailedPasswordAttempts)
admin.wipeData()
}

override fun onDisabled(context: Context, intent: Intent) {
super.onDisabled(context, intent)
if (Preferences(context).isServiceEnabled)
if (Preferences(context).isEnabled)
Toast.makeText(context, R.string.service_unavailable_popup, Toast.LENGTH_SHORT).show()
}

Expand Down
19 changes: 7 additions & 12 deletions app/src/main/java/me/lucky/sentry/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package me.lucky.sentry
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
Expand All @@ -12,10 +11,6 @@ import com.google.android.material.snackbar.Snackbar
import me.lucky.sentry.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
companion object {
private val TAG = MainActivity::class.simpleName
}

private lateinit var binding: ActivityMainBinding
private lateinit var prefs: Preferences
private lateinit var admin: DeviceAdminManager
Expand All @@ -41,14 +36,15 @@ class MainActivity : AppCompatActivity() {
private fun init() {
prefs = Preferences(this)
admin = DeviceAdminManager(this)
if (!packageManager.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN))
hideSecureLockScreenRequired()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
!packageManager.hasSystemFeature(PackageManager.FEATURE_SECURE_LOCK_SCREEN))
hideSecureLockScreenRequired()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S || !admin.canUsbDataSignalingBeDisabled())
hideUsbDataSignaling()
binding.apply {
maxFailedPasswordAttempts.value = prefs.maxFailedPasswordAttempts.toFloat()
usbDataSignaling.isChecked = isUsbDataSignalingEnabled()
toggle.isChecked = prefs.isServiceEnabled
toggle.isChecked = prefs.isEnabled
}
}

Expand All @@ -66,7 +62,6 @@ class MainActivity : AppCompatActivity() {
try {
admin.setUsbDataSignalingEnabled(isChecked)
} catch (exc: Exception) {
Log.e(TAG, "usbDataSignaling", exc)
Snackbar.make(
usbDataSignaling,
R.string.usb_data_signaling_change_failed_popup,
Expand Down Expand Up @@ -97,19 +92,19 @@ class MainActivity : AppCompatActivity() {
}

private fun setOn() {
prefs.isServiceEnabled = true
prefs.isEnabled = true
}

private fun setOff() {
prefs.isServiceEnabled = false
prefs.isEnabled = false
admin.remove()
}

private fun update() {
binding.apply {
usbDataSignaling.isChecked = isUsbDataSignalingEnabled()
}
if (prefs.isServiceEnabled && !admin.isActive())
if (prefs.isEnabled && !admin.isActive())
Snackbar.make(
binding.toggle,
R.string.service_unavailable_popup,
Expand Down
19 changes: 5 additions & 14 deletions app/src/main/java/me/lucky/sentry/NotificationListenerService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@ import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.service.notification.NotificationListenerService
import android.util.Log
import androidx.annotation.RequiresApi
import java.lang.Exception

class NotificationListenerService : NotificationListenerService() {
companion object {
private val TAG = NotificationListenerService::class.simpleName
}

private val lockReceiver = LockReceiver()

override fun onCreate() {
Expand Down Expand Up @@ -52,25 +46,22 @@ class NotificationListenerService : NotificationListenerService() {
private class LockReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S ||
!Preferences(context ?: return).isServiceEnabled) return
!Preferences(context ?: return).isEnabled) return
when (intent?.action) {
Intent.ACTION_USER_PRESENT -> {
if (context.getSystemService(KeyguardManager::class.java)
?.isDeviceSecure != true) return
setUsbDataSignalingEnabled(context, true, "user present")
setUsbDataSignalingEnabled(context, true)
}
Intent.ACTION_SCREEN_OFF ->
setUsbDataSignalingEnabled(context, false, "screen off")
Intent.ACTION_SCREEN_OFF -> setUsbDataSignalingEnabled(context, false)
}
}

@RequiresApi(Build.VERSION_CODES.S)
private fun setUsbDataSignalingEnabled(ctx: Context, enabled: Boolean, msg: String) {
private fun setUsbDataSignalingEnabled(ctx: Context, enabled: Boolean) {
try {
DeviceAdminManager(ctx).setUsbDataSignalingEnabled(enabled)
} catch (exc: Exception) {
Log.e(TAG, msg, exc)
}
} catch (exc: Exception) {}
}
}
}
10 changes: 6 additions & 4 deletions app/src/main/java/me/lucky/sentry/Preferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ import androidx.security.crypto.MasterKeys

class Preferences(ctx: Context) {
companion object {
private const val SERVICE_ENABLED = "service_enabled"
private const val ENABLED = "enabled"
private const val MAX_FAILED_PASSWORD_ATTEMPTS = "max_failed_password_attempts"

private const val FILE_NAME = "sec_shared_prefs"
// migration
private const val SERVICE_ENABLED = "service_enabled"
}

private val mk = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
Expand All @@ -22,9 +24,9 @@ class Preferences(ctx: Context) {
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM,
)

var isServiceEnabled: Boolean
get() = prefs.getBoolean(SERVICE_ENABLED, false)
set(value) = prefs.edit { putBoolean(SERVICE_ENABLED, value) }
var isEnabled: Boolean
get() = prefs.getBoolean(ENABLED, prefs.getBoolean(SERVICE_ENABLED, false))
set(value) = prefs.edit { putBoolean(ENABLED, value) }

var maxFailedPasswordAttempts: Int
get() = prefs.getInt(MAX_FAILED_PASSWORD_ATTEMPTS, 0)
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.1.2' apply false
id 'com.android.library' version '7.1.2' apply false
id 'com.android.application' version '7.2.1' apply false
id 'com.android.library' version '7.2.1' apply false
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
}

Expand Down
1 change: 1 addition & 0 deletions fastlane/metadata/android/en-US/changelogs/3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix max failed password attempts not showing on Android before Q
5 changes: 2 additions & 3 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#Sat Feb 19 09:22:29 MSK 2022
#Sun Jun 12 01:10:07 MSK 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
distributionSha256Sum=f581709a9c35e9cb92e16f585d2c4bc99b2b1a5f85d2badbd3dc6bff59e1e6dd

0 comments on commit 4812468

Please sign in to comment.