Skip to content

Commit

Permalink
Optimize code
Browse files Browse the repository at this point in the history
  • Loading branch information
BinTianqi committed Dec 29, 2024
1 parent 4250d47 commit 937afe9
Show file tree
Hide file tree
Showing 15 changed files with 513 additions and 750 deletions.
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-sdk tools:overrideLibrary="rikka.shizuku.provider,rikka.shizuku.api,rikka.shizuku.shared,rikka.shizuku.aidl"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.bintianqi.owndroid

import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
Expand Down Expand Up @@ -47,7 +46,6 @@ class InstallAppActivity: FragmentActivity() {
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
val context = applicationContext
val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE)
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val uri = this.intent.data!!
var apkInfoText by mutableStateOf(context.getString(R.string.parsing_apk_info))
Expand Down Expand Up @@ -97,7 +95,9 @@ class InstallAppActivity: FragmentActivity() {
TextButton(
onClick = {
status = "installing"
uriToStream(applicationContext, this.intent.data) { stream -> installPackage(applicationContext, stream) }
intent.data?.let {
uriToStream(applicationContext, it) { stream -> installPackage(applicationContext, stream) }
}
},
enabled = status != "installing"
) {
Expand Down
10 changes: 8 additions & 2 deletions app/src/main/java/com/bintianqi/owndroid/Receiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import android.util.Log
import android.widget.Toast
import androidx.core.app.NotificationCompat
import com.bintianqi.owndroid.dpm.handleNetworkLogs
import com.bintianqi.owndroid.dpm.handleSecurityLogs
import com.bintianqi.owndroid.dpm.isDeviceAdmin
import com.bintianqi.owndroid.dpm.isDeviceOwner
import com.bintianqi.owndroid.dpm.isProfileOwner
import com.bintianqi.owndroid.dpm.processSecurityLogs
import com.bintianqi.owndroid.dpm.toggleInstallAppActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
Expand Down Expand Up @@ -78,7 +78,13 @@ class Receiver : DeviceAdminReceiver() {
super.onSecurityLogsAvailable(context, intent)
if(VERSION.SDK_INT >= 24) {
CoroutineScope(Dispatchers.IO).launch {
handleSecurityLogs(context)
val events = getManager(context).retrieveSecurityLogs(ComponentName(context, this@Receiver::class.java)) ?: return@launch
val file = context.filesDir.resolve("SecurityLogs.json")
val fileExists = file.exists()
file.outputStream().use {
if(fileExists) it.write(",".encodeToByteArray())
processSecurityLogs(events, it)
}
}
}
}
Expand Down
47 changes: 19 additions & 28 deletions app/src/main/java/com/bintianqi/owndroid/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build.VERSION
import android.widget.Toast
import androidx.biometric.BiometricManager
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.isSystemInDarkTheme
Expand Down Expand Up @@ -44,11 +43,11 @@ import java.security.SecureRandom
@Composable
fun Settings(navCtrl: NavHostController) {
MyScaffold(R.string.settings, 0.dp, navCtrl) {
FunctionItem(R.string.options, "", R.drawable.tune_fill0) { navCtrl.navigate("Options") }
FunctionItem(R.string.appearance, "", R.drawable.format_paint_fill0) { navCtrl.navigate("Appearance") }
FunctionItem(R.string.security, "", R.drawable.lock_fill0) { navCtrl.navigate("AuthSettings") }
FunctionItem(R.string.api, "", R.drawable.apps_fill0) { navCtrl.navigate("ApiSettings") }
FunctionItem(R.string.about, "", R.drawable.info_fill0) { navCtrl.navigate("About") }
FunctionItem(title = R.string.options, icon = R.drawable.tune_fill0) { navCtrl.navigate("Options") }
FunctionItem(title = R.string.appearance, icon = R.drawable.format_paint_fill0) { navCtrl.navigate("Appearance") }
FunctionItem(title = R.string.security, icon = R.drawable.lock_fill0) { navCtrl.navigate("AuthSettings") }
FunctionItem(title = R.string.api, icon = R.drawable.apps_fill0) { navCtrl.navigate("ApiSettings") }
FunctionItem(title = R.string.about, icon = R.drawable.info_fill0) { navCtrl.navigate("About") }
}
}

Expand All @@ -57,9 +56,9 @@ fun SettingsOptions(navCtrl: NavHostController) {
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
MyScaffold(R.string.options, 0.dp, navCtrl) {
SwitchItem(
R.string.show_dangerous_features, "", R.drawable.warning_fill0,
{ sharedPref.getBoolean("dangerous_features", false) },
{ sharedPref.edit().putBoolean("dangerous_features", it).apply() }
R.string.show_dangerous_features, icon = R.drawable.warning_fill0,
getState = { sharedPref.getBoolean("dangerous_features", false) },
onCheckedChange = { sharedPref.edit().putBoolean("dangerous_features", it).apply() }
)
}
}
Expand All @@ -75,11 +74,7 @@ fun Appearance(navCtrl: NavHostController, vm: MyViewModel) {
}
MyScaffold(R.string.appearance, 0.dp, navCtrl) {
if(VERSION.SDK_INT >= 31) {
SwitchItem(
R.string.material_you_color, "", null,
theme.materialYou,
{ vm.theme.value = theme.copy(materialYou = it) }
)
SwitchItem(R.string.material_you_color, state = theme.materialYou, onCheckedChange = { vm.theme.value = theme.copy(materialYou = it) })
}
Box {
FunctionItem(R.string.dark_theme, stringResource(darkThemeTextID)) { darkThemeMenu = true }
Expand Down Expand Up @@ -111,11 +106,7 @@ fun Appearance(navCtrl: NavHostController, vm: MyViewModel) {
}
}
AnimatedVisibility(theme.darkTheme == true || (theme.darkTheme == null && isSystemInDarkTheme())) {
SwitchItem(
R.string.black_theme, "", null,
theme.blackTheme,
{ vm.theme.value = theme.copy(blackTheme = it) }
)
SwitchItem(R.string.black_theme, state = theme.blackTheme, onCheckedChange = { vm.theme.value = theme.copy(blackTheme = it) })
}
}
}
Expand All @@ -127,8 +118,8 @@ fun AuthSettings(navCtrl: NavHostController) {
var auth by remember{ mutableStateOf(sharedPref.getBoolean("auth",false)) }
MyScaffold(R.string.security, 0.dp, navCtrl) {
SwitchItem(
R.string.lock_owndroid, "", null, auth,
{
R.string.lock_owndroid, state = auth,
onCheckedChange = {
sharedPref.edit().putBoolean("auth", it).apply()
auth = sharedPref.getBoolean("auth", false)
}
Expand All @@ -143,13 +134,13 @@ fun AuthSettings(navCtrl: NavHostController) {
}
}
SwitchItem(
R.string.enable_bio_auth, "", null, bioAuth != 0,
{ bioAuth = if(it) 1 else 0; sharedPref.edit().putInt("biometrics_auth", bioAuth).apply() }, bioAuth != 2
R.string.enable_bio_auth, state = bioAuth != 0,
onCheckedChange = { bioAuth = if(it) 1 else 0; sharedPref.edit().putInt("biometrics_auth", bioAuth).apply() }, enabled = bioAuth != 2
)
SwitchItem(
R.string.lock_in_background, "", null,
{ sharedPref.getBoolean("lock_in_background", false) },
{ sharedPref.edit().putBoolean("lock_in_background", it).apply() }
R.string.lock_in_background,
getState = { sharedPref.getBoolean("lock_in_background", false) },
onCheckedChange = { sharedPref.edit().putBoolean("lock_in_background", it).apply() }
)
}
}
Expand All @@ -167,7 +158,7 @@ fun ApiSettings(navCtrl: NavHostController) {
if(!enabled) remove("api_key")
}
}
SwitchItem(R.string.enable, "", null, enabled, { enabled = it }, padding = false)
SwitchItem(R.string.enable, state = enabled, onCheckedChange = { enabled = it }, padding = false)
if(enabled) {
var key by remember { mutableStateOf("") }
OutlinedTextField(
Expand All @@ -189,7 +180,7 @@ fun ApiSettings(navCtrl: NavHostController) {
modifier = Modifier.fillMaxWidth().padding(bottom = 10.dp),
onClick = {
sharedPref.edit().putString("api_key", key).apply()
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
context.showOperationResultToast(true)
}
) {
Text(stringResource(R.string.apply))
Expand Down
57 changes: 8 additions & 49 deletions app/src/main/java/com/bintianqi/owndroid/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@ import android.content.ClipData
import android.content.ClipboardManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.annotation.StringRes
import com.bintianqi.owndroid.dpm.addDeviceAdmin
import com.bintianqi.owndroid.dpm.createManagedProfile
import kotlinx.coroutines.flow.MutableStateFlow
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
Expand All @@ -27,29 +22,20 @@ import java.time.format.DateTimeFormatter
import java.util.Date
import java.util.Locale

lateinit var getFile: ActivityResultLauncher<Intent>
val fileUriFlow = MutableStateFlow(Uri.parse(""))

var zhCN = true

fun uriToStream(
context: Context,
uri: Uri?,
uri: Uri,
operation: (stream: InputStream)->Unit
){
if(uri!=null){
try {
val stream = context.contentResolver.openInputStream(uri)
if(stream != null) { operation(stream) }
stream?.close()
}
catch(_: FileNotFoundException) { Toast.makeText(context, R.string.file_not_exist, Toast.LENGTH_SHORT).show() }
catch(_: IOException) { Toast.makeText(context, R.string.io_exception, Toast.LENGTH_SHORT).show() }
try {
val stream = context.contentResolver.openInputStream(uri)
if(stream != null) { operation(stream) }
stream?.close()
}
}

fun MutableList<Int>.toggle(status: Boolean, element: Int) {
if(status) add(element) else remove(element)
catch(_: FileNotFoundException) { Toast.makeText(context, R.string.file_not_exist, Toast.LENGTH_SHORT).show() }
catch(_: IOException) { Toast.makeText(context, R.string.io_exception, Toast.LENGTH_SHORT).show() }
}

fun writeClipBoard(context: Context, string: String):Boolean{
Expand All @@ -62,40 +48,13 @@ fun writeClipBoard(context: Context, string: String):Boolean{
return true
}

lateinit var exportFile: ActivityResultLauncher<Intent>
var exportFilePath: String? = null
var isExportingSecurityOrNetworkLogs = false

fun registerActivityResult(context: ComponentActivity){
getFile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
activityResult.data.let {
if(it != null) fileUriFlow.value = it.data
}
}
createManagedProfile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
fun registerActivityResult(context: ComponentActivity) {
addDeviceAdmin = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
val dpm = context.applicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
if(dpm.isAdminActive(ComponentName(context.applicationContext, Receiver::class.java))) {
backToHomeStateFlow.value = true
}
}
exportFile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val intentData = result.data ?: return@registerForActivityResult
val uriData = intentData.data ?: return@registerForActivityResult
val path = exportFilePath ?: return@registerForActivityResult
context.contentResolver.openOutputStream(uriData).use { outStream ->
if(outStream != null) {
if(isExportingSecurityOrNetworkLogs) outStream.write("[".encodeToByteArray())
File(path).inputStream().use { inStream ->
inStream.copyTo(outStream)
}
if(isExportingSecurityOrNetworkLogs) outStream.write("]".encodeToByteArray())
Toast.makeText(context.applicationContext, R.string.success, Toast.LENGTH_SHORT).show()
}
}
isExportingSecurityOrNetworkLogs = false
exportFilePath = null
}
}

fun formatFileSize(bytes: Long): String {
Expand Down
Loading

0 comments on commit 937afe9

Please sign in to comment.