Skip to content

Commit

Permalink
fix: #245
Browse files Browse the repository at this point in the history
Change-Id: I73f039a88b05f5e1749a51851e7828932b609bc4
  • Loading branch information
XayahSuSuSu committed Jul 8, 2024
1 parent 8667f96 commit 4f65309
Show file tree
Hide file tree
Showing 19 changed files with 209 additions and 17 deletions.
5 changes: 5 additions & 0 deletions source/app/src/main/res/values-zh-rCN/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,9 @@
<string name="translators">翻译者</string>
<string name="translators_desc">感谢他们的付出</string>
<string name="no_root_directory">请勿选择根目录</string>
<string name="option_i">方案I</string>
<string name="option_ii">方案II</string>
<string name="disabled">禁用</string>
<string name="kill_app_options">杀死应用选项</string>
<string name="kill_app_options_desc">备份应用前行为</string>
</resources>
5 changes: 5 additions & 0 deletions source/app/src/main/res/values-zh-rHK/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,9 @@
<string name="translators">翻譯者</string>
<string name="translators_desc">感謝他們的付出</string>
<string name="no_root_directory">請勿選擇根目錄</string>
<string name="option_i">方案I</string>
<string name="option_ii">方案II</string>
<string name="disabled">禁用</string>
<string name="kill_app_options">殺死應用選項</string>
<string name="kill_app_options_desc">備份應用前行爲</string>
</resources>
5 changes: 5 additions & 0 deletions source/app/src/main/res/values-zh-rTW/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,9 @@
<string name="translators">翻譯者</string>
<string name="translators_desc">感謝他們的付出</string>
<string name="no_root_directory">請勿選擇根目錄</string>
<string name="option_i">Option One</string>
<string name="option_ii">Option II</string>
<string name="disabled">禁用</string>
<string name="kill_app_options">殺死應用選項</string>
<string name="kill_app_options_desc">備份應用前行爲</string>
</resources>
5 changes: 5 additions & 0 deletions source/app/src/main/res/values/arrays.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@
<item>@string/password</item>
<item>@string/public_key</item>
</string-array>
<string-array name="kill_app_options">
<item>@string/disabled</item>
<item>@string/option_i</item>
<item>@string/option_ii</item>
</string-array>
</resources>
5 changes: 5 additions & 0 deletions source/app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,9 @@
<string name="translators">Translators</string>
<string name="translators_desc">We appreciate their efforts</string>
<string name="no_root_directory">Please do not select the root directory</string>
<string name="option_i">Option One</string>
<string name="option_ii">Option II</string>
<string name="disabled">Disabled</string>
<string name="kill_app_options">Killing app options</string>
<string name="kill_app_options_desc">Behavior before backup</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.xayah.core.model.CompressionType
import com.xayah.core.model.KillAppOption
import com.xayah.core.model.SelectionType
import com.xayah.core.model.ThemeType
import com.xayah.core.model.util.of
Expand All @@ -22,6 +23,7 @@ val KeyUserIdList = stringPreferencesKey("user_id_list")
val KeyBackupUserIdIndex = stringPreferencesKey("backup_user_id_index")
val KeyRestoreUserIdIndex = stringPreferencesKey("restore_user_id_index")
val KeyCustomSUFile = stringPreferencesKey("custom_su_file")
val KeyKillAppOption = stringPreferencesKey("kill_app_option")


// -----------------------------------------Read-----------------------------------------
Expand All @@ -34,6 +36,7 @@ fun Context.readThemeType() = readStoreString(key = KeyThemeType, defValue = "")
fun Context.readUserIdList() = readStoreString(key = KeyUserIdList, defValue = "[0]").map { Gson().fromJson<List<Int>>(it, object : TypeToken<List<Int>>() {}.type) }
fun Context.readBackupUserIdIndex() = readStoreString(key = KeyBackupUserIdIndex, defValue = "[0]").map { Gson().fromJson<List<Int>>(it, object : TypeToken<List<Int>>() {}.type) }
fun Context.readRestoreUserIdIndex() = readStoreString(key = KeyRestoreUserIdIndex, defValue = "[0]").map { Gson().fromJson<List<Int>>(it, object : TypeToken<List<Int>>() {}.type) }
fun Context.readKillAppOption() = readStoreString(key = KeyKillAppOption, defValue = "").map { KillAppOption.of(it) }

/**
* The final path for saving the backup.
Expand All @@ -55,3 +58,4 @@ suspend fun Context.saveBackupUserIdIndex(value: List<Int>) = saveStoreString(ke
suspend fun Context.saveRestoreUserIdIndex(value: List<Int>) = saveStoreString(key = KeyRestoreUserIdIndex, value = Gson().toJson(value))
suspend fun Context.saveBackupSavePath(value: String) = saveStoreString(key = KeyBackupSavePath, value = value.trim())
suspend fun Context.saveCustomSUFile(value: String) = saveStoreString(key = KeyCustomSUFile, value = value.trim())
suspend fun Context.saveKillAppOption(value: KillAppOption) = saveStoreString(key = KeyKillAppOption, value = value.name.trim())
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package android.app;

import dev.rikka.tools.refine.RefineAs;

/**
* @see <a href="https://cs.android.com/android/platform/superproject/+/android-8.0.0_r51:frameworks/base/core/java/android/app/ActivityManager.java;l=3765">ActivityManager.java</a>
*/
@RefineAs(ActivityManager.class)
public class ActivityManagerHidden {
public void forceStopPackageAsUser(String packageName, int userId) {
throw new RuntimeException("Stub!");
}
}
16 changes: 12 additions & 4 deletions source/core/model/src/main/kotlin/com/xayah/core/model/Enum.kt
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ enum class SmbVersion(val text: String) {
SMB_3_1_1("3.1.1"),
}

enum class SmbAuthMode(val index: Int) {
PASSWORD(0),
GUEST(1),
ANONYMOUS(2);
enum class SmbAuthMode() {
PASSWORD,
GUEST,
ANONYMOUS;

companion object
}
Expand Down Expand Up @@ -153,3 +153,11 @@ enum class ThemeType {

companion object
}

enum class KillAppOption {
DISABLED,
OPTION_I,
OPTION_II;

companion object
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.xayah.core.model.util

import com.xayah.core.model.CompressionType
import com.xayah.core.model.KillAppOption
import com.xayah.core.model.LZ4_SUFFIX
import com.xayah.core.model.OpType
import com.xayah.core.model.SFTPAuthMode
Expand Down Expand Up @@ -64,3 +65,12 @@ fun SFTPAuthMode.Companion.indexOf(index: Int): SFTPAuthMode = when (index) {
1 -> SFTPAuthMode.PUBLIC_KEY
else -> SFTPAuthMode.PASSWORD
}

fun KillAppOption.Companion.indexOf(index: Int): KillAppOption = when (index) {
1 -> KillAppOption.OPTION_I
2 -> KillAppOption.OPTION_II
else -> KillAppOption.DISABLED
}

fun KillAppOption.Companion.of(name: String?): KillAppOption =
runCatching { KillAppOption.valueOf(name!!.uppercase()) }.getOrDefault(KillAppOption.OPTION_II)
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface IRemoteRootService {
void setDisplayPowerMode(int mode);
int getScreenOffTimeout();
void setScreenOffTimeout(int timeout);
void forceStopPackageAsUser(String packageName, int userId);

String calculateMD5(String src);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.xayah.core.rootservice.impl

import android.app.ActivityManagerHidden
import android.app.ActivityThread
import android.app.usage.StorageStats
import android.app.usage.StorageStatsManager
Expand Down Expand Up @@ -52,13 +53,16 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() {
private var packageManagerHidden: PackageManagerHidden
private var storageStatsManager: StorageStatsManager
private var userManager: UserManagerHidden
private var activityManager: ActivityManagerHidden

private fun getSystemContext(): Context = ActivityThread.systemMain().systemContext

private fun getStorageStatsManager(): StorageStatsManager = systemContext.getSystemService(Context.STORAGE_STATS_SERVICE) as StorageStatsManager

private fun getUserManager(): UserManagerHidden = UserManagerHidden.get(systemContext).castTo()

private fun getActivityManager(): ActivityManagerHidden = systemContext.getSystemService(Context.ACTIVITY_SERVICE).castTo()

init {
/**
* If [ParcelTmpFilePath] has incorrect SELinux context, the transaction will get failed:
Expand All @@ -84,6 +88,7 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() {
packageManagerHidden = packageManager.castTo()
storageStatsManager = getStorageStatsManager()
userManager = getUserManager()
activityManager = getActivityManager()
}

override fun readStatFs(path: String): StatFsParcelable = synchronized(lock) {
Expand Down Expand Up @@ -380,5 +385,9 @@ internal class RemoteRootServiceImpl : IRemoteRootService.Stub() {
ShellUtils.fastCmd("settings put system screen_off_timeout $timeout")
}

override fun forceStopPackageAsUser(packageName: String, userId: Int) = synchronized(lock) {
activityManager.forceStopPackageAsUser(packageName, userId)
}

override fun calculateMD5(src: String): String = synchronized(lock) { HashUtil.calculateMD5(src) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ class RemoteRootService(private val context: Context) {
suspend fun setScreenOffTimeout(timeout: Int) =
runCatching { getService().setScreenOffTimeout(timeout) }.onFailure(onFailure)

suspend fun forceStopPackageAsUser(packageName: String, userId: Int) =
runCatching { getService().forceStopPackageAsUser(packageName, userId) }.onFailure(onFailure)

suspend fun calculateMD5(src: String): String? =
runCatching { getService().calculateMD5(src) }.onFailure(onFailure).getOrNull()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import com.xayah.core.data.repository.TaskRepository
import com.xayah.core.database.dao.PackageDao
import com.xayah.core.database.dao.TaskDao
import com.xayah.core.datastore.readAutoScreenOff
import com.xayah.core.datastore.readKillAppOption
import com.xayah.core.datastore.readResetBackupList
import com.xayah.core.datastore.readScreenOffTimeout
import com.xayah.core.datastore.readSelectionType
import com.xayah.core.datastore.saveLastBackupTime
import com.xayah.core.datastore.saveScreenOffCountDown
import com.xayah.core.datastore.saveScreenOffTimeout
import com.xayah.core.model.DataType
import com.xayah.core.model.KillAppOption
import com.xayah.core.model.OpType
import com.xayah.core.model.OperationState
import com.xayah.core.model.ProcessingType
Expand Down Expand Up @@ -238,6 +240,9 @@ internal abstract class BackupService : Service() {
taskDao.upsert(it)
}

val killAppOption = context.readKillAppOption().first()
log { "Kill app option: $killAppOption" }

pkgEntities.forEachIndexed { index, pkg ->
NotificationUtil.notify(
context,
Expand All @@ -250,8 +255,21 @@ internal abstract class BackupService : Service() {
log { "Current package: ${pkg.packageEntity}" }

// Kill the package.
log { "Trying to kill ${pkg.packageEntity.packageName}." }
BaseUtil.killPackage(context = context, userId = pkg.packageEntity.userId, packageName = pkg.packageEntity.packageName)
when (killAppOption) {
KillAppOption.DISABLED -> {
log { "Won't kill ${pkg.packageEntity.packageName}." }
}

KillAppOption.OPTION_I -> {
log { "Trying to kill ${pkg.packageEntity.packageName}." }
BaseUtil.killPackage(context = context, userId = pkg.packageEntity.userId, packageName = pkg.packageEntity.packageName)
}

KillAppOption.OPTION_II -> {
log { "Trying to kill ${pkg.packageEntity.packageName}." }
rootService.forceStopPackageAsUser(pkg.packageEntity.packageName, pkg.packageEntity.userId)
}
}

runCatchingOnService { backupPackage(pkg) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.xayah.core.data.repository.TaskRepository
import com.xayah.core.database.dao.PackageDao
import com.xayah.core.database.dao.TaskDao
import com.xayah.core.datastore.readAutoScreenOff
import com.xayah.core.datastore.readKillAppOption
import com.xayah.core.datastore.readResetRestoreList
import com.xayah.core.datastore.readRestoreUser
import com.xayah.core.datastore.readScreenOffTimeout
Expand All @@ -19,6 +20,7 @@ import com.xayah.core.datastore.saveLastRestoreTime
import com.xayah.core.datastore.saveScreenOffCountDown
import com.xayah.core.datastore.saveScreenOffTimeout
import com.xayah.core.model.DataType
import com.xayah.core.model.KillAppOption
import com.xayah.core.model.OpType
import com.xayah.core.model.OperationState
import com.xayah.core.model.ProcessingType
Expand Down Expand Up @@ -206,6 +208,8 @@ internal abstract class RestoreService : Service() {
taskDao.upsert(it)
}

val killAppOption = context.readKillAppOption().first()

pkgEntities.forEachIndexed { index, pkg ->
NotificationUtil.notify(
context,
Expand All @@ -218,8 +222,21 @@ internal abstract class RestoreService : Service() {
log { "Current package: ${pkg.packageEntity}" }

// Kill the package.
log { "Trying to kill ${pkg.packageEntity.packageName}." }
BaseUtil.killPackage(context = context, userId = pkg.packageEntity.userId, packageName = pkg.packageEntity.packageName)
when (killAppOption) {
KillAppOption.DISABLED -> {
log { "Won't kill ${pkg.packageEntity.packageName}." }
}

KillAppOption.OPTION_I -> {
log { "Trying to kill ${pkg.packageEntity.packageName}." }
BaseUtil.killPackage(context = context, userId = pkg.packageEntity.userId, packageName = pkg.packageEntity.packageName)
}

KillAppOption.OPTION_II -> {
log { "Trying to kill ${pkg.packageEntity.packageName}." }
rootService.forceStopPackageAsUser(pkg.packageEntity.packageName, pkg.packageEntity.userId)
}
}

runCatchingOnService { restorePackage(pkg) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ fun PageSMBSetup() {
var share by rememberSaveable(uiState.cloudEntity) { mutableStateOf(uiState.cloudEntity?.getExtraEntity<SMBExtra>()?.share ?: "") }
var username by rememberSaveable(uiState.cloudEntity) { mutableStateOf(uiState.cloudEntity?.user ?: "") }
val modeOptions = stringArrayResource(id = R.array.smb_auth_mode).toList()
var modeIndex by rememberSaveable(uiState.cloudEntity) { mutableIntStateOf(uiState.cloudEntity?.getExtraEntity<SMBExtra>()?.mode?.index ?: 0) }
var modeIndex by rememberSaveable(uiState.cloudEntity) { mutableIntStateOf(uiState.cloudEntity?.getExtraEntity<SMBExtra>()?.mode?.ordinal ?: 0) }
var password by rememberSaveable(uiState.cloudEntity) { mutableStateOf(uiState.cloudEntity?.pass ?: "") }
var passwordVisible by rememberSaveable { mutableStateOf(false) }
val allFilled by rememberSaveable(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,12 @@ fun PageSettings() {
) {
navController.navigate(MainRoutes.BackupSettings.route)
}
/**
* Clickable(
* icon = ImageVectorToken.fromDrawable(R.drawable.ic_rounded_history),
* title = StringResourceToken.fromStringId(R.string.restore_settings),
* ) {
* navController.navigate(MainRoutes.RestoreSettings.route)
* }
*/
Clickable(
icon = ImageVectorToken.fromDrawable(R.drawable.ic_rounded_history),
title = StringResourceToken.fromStringId(R.string.restore_settings),
) {
navController.navigate(MainRoutes.RestoreSettings.route)
}
Clickable(
title = StringResourceToken.fromStringId(R.string.setup),
value = StringResourceToken.fromStringId(R.string.enter_the_setup_page_again),
Expand Down
Loading

0 comments on commit 4f65309

Please sign in to comment.