Skip to content

Commit

Permalink
add basic auth (PIN)
Browse files Browse the repository at this point in the history
  • Loading branch information
BinTianqi committed May 14, 2024
1 parent 5aa3c55 commit 11bd8a2
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 16 deletions.
8 changes: 6 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ android {
versionCode = 27
versionName = "5.2"
multiDexEnabled = false
signingConfig = signingConfigs.getByName("testkey")
}

buildTypes {
release {
project.gradle.startParameter.excludedTaskNames.add("lint")
//project.gradle.startParameter.excludedTaskNames.add("lint")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
signingConfig = signingConfigs.getByName("testkey")
}
debug {
signingConfig = signingConfigs.getByName("testkey")
}
}
compileOptions {
Expand Down Expand Up @@ -75,4 +78,5 @@ dependencies {
implementation(libs.androidx.navigation.compose)
implementation(libs.shizuku.provider)
implementation(libs.shizuku.api)
implementation(libs.androidx.biometric)
}
5 changes: 4 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".AuthActivity"
android:theme="@style/Theme.OwnDroid">
</activity>
<receiver
android:name=".Receiver"
android:description="@string/app_name"
Expand Down
92 changes: 92 additions & 0 deletions app/src/main/java/com/bintianqi/owndroid/Auth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.bintianqi.owndroid

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricPrompt
import androidx.biometric.BiometricPrompt.AuthenticationCallback
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentActivity
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme

var authenticated = false

class AuthActivity: FragmentActivity(){
@SuppressLint("UnrememberedMutableState")
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
val mainActivityIntent = Intent(applicationContext, MainActivity::class.java)
val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE)
val callback = object: AuthenticationCallback() {
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {
super.onAuthenticationSucceeded(result)
authenticated = true
startActivity(mainActivityIntent)
finish()
}
override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {
super.onAuthenticationError(errorCode, errString)
Toast.makeText(applicationContext, errString, Toast.LENGTH_SHORT).show()
/*if (errString.toString().isNotEmpty()) {
}*/
}
}
setContent {
val materialYou = mutableStateOf(sharedPref.getBoolean("material_you",true))
val blackTheme = mutableStateOf(sharedPref.getBoolean("black_theme", false))
OwnDroidTheme(materialYou.value, blackTheme.value) {
Auth(this, callback)
}
}
}
}

@Composable
fun Auth(activity: FragmentActivity, callback: AuthenticationCallback) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxSize()
){
Text(text = "Authenticate", style = MaterialTheme.typography.headlineLarge)
Button(
onClick = {
authWithBiometricPrompt(activity, callback)
}
){
Text(text = "Start")
}
}
}

private fun authWithBiometricPrompt(activity: FragmentActivity, callback: AuthenticationCallback) {
val executor = ContextCompat.getMainExecutor(activity.applicationContext)
val biometricPrompt = BiometricPrompt(activity, executor, callback)
val promptInfo = BiometricPrompt.PromptInfo.Builder()
.setAllowedAuthenticators(BiometricManager.Authenticators.DEVICE_CREDENTIAL)
.setTitle("Auth")
.setConfirmationRequired(true)
.setSubtitle("Enter password")
.build()
biometricPrompt.authenticate(promptInfo)
}
32 changes: 19 additions & 13 deletions app/src/main/java/com/bintianqi/owndroid/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION
import android.os.Bundle
import android.widget.Toast
Expand Down Expand Up @@ -33,6 +34,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentActivity
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -45,9 +47,13 @@ import java.util.Locale

var backToHome = false
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() {
class MainActivity : FragmentActivity() {
@SuppressLint("UnrememberedMutableState")
override fun onCreate(savedInstanceState: Bundle?) {
if(!authenticated){
startActivity(Intent(applicationContext, AuthActivity::class.java))
finish()
}
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
Expand Down Expand Up @@ -96,18 +102,18 @@ fun MyScaffold(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolea
popEnterTransition = Animations.navHostPopEnterTransition,
popExitTransition = Animations.navHostPopExitTransition
){
composable(route = "HomePage", content = { HomePage(navCtrl, pkgName)})
composable(route = "SystemManage", content = { SystemManage(navCtrl) })
composable(route = "ManagedProfile", content = {ManagedProfile(navCtrl)})
composable(route = "Permissions", content = { DpmPermissions(navCtrl)})
composable(route = "ApplicationManage", content = { ApplicationManage(navCtrl, pkgName, dialogStatus)})
composable(route = "UserRestriction", content = { UserRestriction(navCtrl)})
composable(route = "UserManage", content = { UserManage(navCtrl)})
composable(route = "Password", content = { Password(navCtrl)})
composable(route = "AppSetting", content = { AppSetting(navCtrl, materialYou, blackTheme)})
composable(route = "Network", content = {Network(navCtrl)})
composable(route = "PackageSelector"){PackageSelector(navCtrl, pkgName)}
composable(route = "PermissionPicker"){PermissionPicker(navCtrl)}
composable(route = "HomePage"){ HomePage(navCtrl, pkgName) }
composable(route = "SystemManage"){ SystemManage(navCtrl) }
composable(route = "ManagedProfile"){ ManagedProfile(navCtrl) }
composable(route = "Permissions"){ DpmPermissions(navCtrl) }
composable(route = "ApplicationManage"){ ApplicationManage(navCtrl, pkgName, dialogStatus)}
composable(route = "UserRestriction"){ UserRestriction(navCtrl) }
composable(route = "UserManage"){ UserManage(navCtrl) }
composable(route = "Password"){ Password(navCtrl) }
composable(route = "AppSetting"){ AppSetting(navCtrl, materialYou, blackTheme) }
composable(route = "Network"){ Network(navCtrl) }
composable(route = "PackageSelector"){ PackageSelector(navCtrl, pkgName) }
composable(route = "PermissionPicker"){ PermissionPicker(navCtrl) }
}
LaunchedEffect(Unit){
val profileInited = sharedPref.getBoolean("ManagedProfileActivated",false)
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ navigation-compose = "2.7.7"
material3 = "1.2.1"
accompanist-drawablepainter = "0.35.0-alpha"
shizuku = "13.1.5"
biometric = "1.2.0-alpha05"

[libraries]
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" }
Expand All @@ -16,6 +17,7 @@ androidx-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
androidx-ui = { module = "androidx.compose.ui:ui" }

accompanist-drawablepainter = { module = "com.google.accompanist:accompanist-drawablepainter", version.ref = "accompanist-drawablepainter" }
androidx-biometric = { group = "androidx.biometric", name = "biometric", version.ref = "biometric" }

shizuku-provider = { module = "dev.rikka.shizuku:provider", version.ref = "shizuku" }
shizuku-api = { module = "dev.rikka.shizuku:api", version.ref = "shizuku" }
Expand Down

0 comments on commit 11bd8a2

Please sign in to comment.