feat: app passcode

This commit is contained in:
rhunk
2023-05-28 09:11:01 +02:00
parent bcaa7b78ae
commit 2aac63ef7a
5 changed files with 117 additions and 4 deletions

View File

@@ -54,6 +54,8 @@
"streak_expiration_info": "Show Streak Expiration Info",
"new_map_ui": "New Map UI",
"use_download_manager": "Use Android Download Manager",
"app_passcode": "Set App Passcode",
"app_lock_on_resume": "App Lock On Resume",
"meo_passcode_bypass": "My Eyes Only Passcode Bypass"
},

View File

@@ -8,10 +8,6 @@ import me.rhunk.snapenhance.Constants
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (intent.getBooleanExtra("is_from_bridge", false)) {
finish()
return
}
packageManager.getLaunchIntentForPackage(Constants.SNAPCHAT_PACKAGE_NAME)?.apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(this)

View File

@@ -213,6 +213,18 @@ enum class ConfigProperty(
ConfigCategory.EXPERIMENTAL,
ConfigStateValue(false)
),
APP_PASSCODE(
"property.app_passcode",
"description.app_passcode",
ConfigCategory.EXPERIMENTAL,
ConfigStringValue("")
),
APP_LOCK_ON_RESUME(
"property.app_lock_on_resume",
"description.app_lock_on_resume",
ConfigCategory.EXPERIMENTAL,
ConfigStateValue(false)
),
MEO_PASSCODE_BYPASS(
"property.meo_passcode_bypass",
"description.meo_passcode_bypass",

View File

@@ -0,0 +1,101 @@
package me.rhunk.snapenhance.features.impl.extras
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.os.Build
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
//TODO: fingerprint unlock
class AppPasscode : Feature("App Passcode", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
private var isLocked = false
private fun setActivityVisibility(isVisible: Boolean) {
context.mainActivity?.let {
it.window.attributes = it.window.attributes.apply { alpha = if (isVisible) 1.0F else 0.0F }
}
}
fun lock() {
if (isLocked) return
isLocked = true
val passcode = context.config.string(ConfigProperty.APP_PASSCODE).also { if (it.isEmpty()) return }
val isDigitPasscode = passcode.all { it.isDigit() }
val mainActivity = context.mainActivity!!
setActivityVisibility(false)
val prompt = AlertDialog.Builder(mainActivity)
val createPrompt = {
val alertDialog = prompt.create()
val textView = EditText(mainActivity)
textView.setSingleLine()
textView.inputType = if (isDigitPasscode) InputType.TYPE_CLASS_NUMBER else InputType.TYPE_CLASS_TEXT
textView.hint = "Code :"
textView.setPadding(100, 100, 100, 100)
textView.addTextChangedListener(object: TextWatcher {
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s.contentEquals(passcode)) {
alertDialog.dismiss()
isLocked = false
setActivityVisibility(true)
}
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun afterTextChanged(s: Editable?) {}
})
alertDialog.setView(textView)
textView.viewTreeObserver.addOnWindowFocusChangeListener { hasFocus ->
if (!hasFocus) return@addOnWindowFocusChangeListener
val imm = mainActivity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(textView, InputMethodManager.SHOW_IMPLICIT)
}
alertDialog.window?.let {
it.attributes.verticalMargin = -0.18F
}
alertDialog.show()
textView.requestFocus()
}
prompt.setOnCancelListener {
createPrompt()
}
createPrompt()
}
@SuppressLint("MissingPermission")
override fun onActivityCreate() {
if (!context.database.hasArroyo()) return
context.runOnUiThread {
lock()
}
if (!context.config.bool(ConfigProperty.APP_LOCK_ON_RESUME)) return
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
context.mainActivity?.registerActivityLifecycleCallbacks(object: android.app.Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: android.app.Activity) { lock() }
override fun onActivityResumed(activity: android.app.Activity) {}
override fun onActivityStarted(activity: android.app.Activity) {}
override fun onActivityDestroyed(activity: android.app.Activity) {}
override fun onActivitySaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle) {}
override fun onActivityStopped(activity: android.app.Activity) {}
override fun onActivityCreated(activity: android.app.Activity, savedInstanceState: android.os.Bundle?) {}
})
}
}
}

View File

@@ -10,6 +10,7 @@ import me.rhunk.snapenhance.features.impl.Messaging
import me.rhunk.snapenhance.features.impl.downloader.AntiAutoDownload
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
import me.rhunk.snapenhance.features.impl.extras.AntiAutoSave
import me.rhunk.snapenhance.features.impl.extras.AppPasscode
import me.rhunk.snapenhance.features.impl.extras.AutoSave
import me.rhunk.snapenhance.features.impl.extras.DisableVideoLengthRestriction
import me.rhunk.snapenhance.features.impl.extras.GalleryMediaSendOverride
@@ -72,6 +73,7 @@ class FeatureManager(private val context: ModContext) : Manager {
register(DisableVideoLengthRestriction::class)
register(MediaQualityLevelOverride::class)
register(MeoPasscodeBypass::class)
register(AppPasscode::class)
initializeFeatures()
}