mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-04-23 19:32:16 +00:00
Add: Root session installer option
This commit is contained in:
parent
a0bf22ab70
commit
465b537d4f
@ -33,6 +33,7 @@ object Preferences {
|
|||||||
Key.ProxyPort,
|
Key.ProxyPort,
|
||||||
Key.ProxyType,
|
Key.ProxyType,
|
||||||
Key.RootPermission,
|
Key.RootPermission,
|
||||||
|
Key.RootSessionInstaller,
|
||||||
Key.SortOrder,
|
Key.SortOrder,
|
||||||
Key.Theme,
|
Key.Theme,
|
||||||
Key.DefaultTab,
|
Key.DefaultTab,
|
||||||
@ -158,6 +159,7 @@ object Preferences {
|
|||||||
)
|
)
|
||||||
|
|
||||||
object RootPermission : Key<Boolean>("root_permission", Value.BooleanValue(false))
|
object RootPermission : Key<Boolean>("root_permission", Value.BooleanValue(false))
|
||||||
|
object RootSessionInstaller : Key<Boolean>("root_session_installer", Value.BooleanValue(false))
|
||||||
|
|
||||||
object SortOrder : Key<Preferences.SortOrder>(
|
object SortOrder : Key<Preferences.SortOrder>(
|
||||||
"sort_order",
|
"sort_order",
|
||||||
|
@ -5,6 +5,9 @@ import android.content.Context
|
|||||||
abstract class BaseInstaller(val context: Context) : InstallationEvents {
|
abstract class BaseInstaller(val context: Context) : InstallationEvents {
|
||||||
companion object {
|
companion object {
|
||||||
const val ROOT_INSTALL_PACKAGE = "cat %s | pm install -i %s --user %s -t -r -S %s"
|
const val ROOT_INSTALL_PACKAGE = "cat %s | pm install -i %s --user %s -t -r -S %s"
|
||||||
|
const val ROOT_INSTALL_PACKAGE_SESSION_CREATE = "pm install-create -i %s --user %s -r -S %s"
|
||||||
|
const val ROOT_INSTALL_PACKAGE_SESSION_WRITE = "cat %s | pm install-write -S %s %s %s"
|
||||||
|
const val ROOT_INSTALL_PACKAGE_SESSION_COMMIT = "pm install-commit %s"
|
||||||
const val ROOT_UNINSTALL_PACKAGE = "pm uninstall --user %s %s"
|
const val ROOT_UNINSTALL_PACKAGE = "pm uninstall --user %s %s"
|
||||||
const val DELETE_PACKAGE = "%s rm %s"
|
const val DELETE_PACKAGE = "%s rm %s"
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package com.looker.droidify.installer
|
package com.looker.droidify.installer
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import com.looker.droidify.BuildConfig
|
||||||
import com.looker.droidify.content.Cache
|
import com.looker.droidify.content.Cache
|
||||||
|
import com.looker.droidify.content.Preferences
|
||||||
import com.looker.droidify.utility.extension.android.Android
|
import com.looker.droidify.utility.extension.android.Android
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class RootInstaller(context: Context) : BaseInstaller(context) {
|
class RootInstaller(context: Context) : BaseInstaller(context) {
|
||||||
|
|
||||||
@ -41,6 +44,27 @@ class RootInstaller(context: Context) : BaseInstaller(context) {
|
|||||||
length()
|
length()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val File.session_install_create
|
||||||
|
get() = String.format(
|
||||||
|
ROOT_INSTALL_PACKAGE_SESSION_CREATE,
|
||||||
|
BuildConfig.APPLICATION_ID,
|
||||||
|
getCurrentUserState,
|
||||||
|
length()
|
||||||
|
)
|
||||||
|
|
||||||
|
fun File.sessionInstallWrite(session_id: Int) = String.format(
|
||||||
|
ROOT_INSTALL_PACKAGE_SESSION_WRITE,
|
||||||
|
absolutePath,
|
||||||
|
length(),
|
||||||
|
session_id,
|
||||||
|
name
|
||||||
|
)
|
||||||
|
|
||||||
|
fun sessionInstallCommit(session_id: Int) = String.format(
|
||||||
|
ROOT_INSTALL_PACKAGE_SESSION_COMMIT,
|
||||||
|
session_id
|
||||||
|
)
|
||||||
|
|
||||||
val String.uninstall
|
val String.uninstall
|
||||||
get() = String.format(
|
get() = String.format(
|
||||||
ROOT_UNINSTALL_PACKAGE,
|
ROOT_UNINSTALL_PACKAGE,
|
||||||
@ -66,14 +90,34 @@ class RootInstaller(context: Context) : BaseInstaller(context) {
|
|||||||
mRootInstaller(cacheFile)
|
mRootInstaller(cacheFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun install(packageName: String, cacheFile: File) = mRootInstaller(cacheFile)
|
override suspend fun install(packageName: String, cacheFile: File) =
|
||||||
|
mRootInstaller(cacheFile)
|
||||||
|
|
||||||
override suspend fun uninstall(packageName: String) = mRootUninstaller(packageName)
|
override suspend fun uninstall(packageName: String) = mRootUninstaller(packageName)
|
||||||
|
|
||||||
private suspend fun mRootInstaller(cacheFile: File) {
|
private suspend fun mRootInstaller(cacheFile: File) {
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
Shell.su(cacheFile.install)
|
if (Preferences[Preferences.Key.RootSessionInstaller]) {
|
||||||
.submit { if (it.isSuccess) Shell.su(cacheFile.deletePackage).submit() }
|
Shell.su(cacheFile.session_install_create)
|
||||||
|
.submit {
|
||||||
|
val sessionIdPattern = Pattern.compile("(\\d+)")
|
||||||
|
val sessionIdMatcher = sessionIdPattern.matcher(it.out[0])
|
||||||
|
val found = sessionIdMatcher.find()
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
val sessionId = sessionIdMatcher.group(1).toInt()
|
||||||
|
Shell.su(cacheFile.sessionInstallWrite(sessionId))
|
||||||
|
.submit {
|
||||||
|
Shell.su(sessionInstallCommit(sessionId)).exec()
|
||||||
|
if (it.isSuccess) Shell.su(cacheFile.deletePackage).submit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Shell.su(cacheFile.install)
|
||||||
|
.submit { if (it.isSuccess) Shell.su(cacheFile.deletePackage).submit() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,12 @@ import com.looker.droidify.R
|
|||||||
import com.looker.droidify.content.Preferences
|
import com.looker.droidify.content.Preferences
|
||||||
import com.looker.droidify.databinding.FragmentPrefsBinding
|
import com.looker.droidify.databinding.FragmentPrefsBinding
|
||||||
import com.looker.droidify.databinding.PreferenceItemBinding
|
import com.looker.droidify.databinding.PreferenceItemBinding
|
||||||
import com.looker.droidify.utility.extension.resources.*
|
import com.looker.droidify.utility.Utils
|
||||||
|
import com.looker.droidify.utility.extension.resources.TypefaceExtra
|
||||||
|
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
||||||
|
import com.looker.droidify.utility.extension.resources.inflate
|
||||||
|
import com.looker.droidify.utility.extension.resources.setTextSizeScaled
|
||||||
|
import com.looker.droidify.utility.extension.resources.sizeScaled
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ -108,11 +113,12 @@ abstract class PrefsNavFragmentX : Fragment() {
|
|||||||
preferences[Preferences.Key.ProxyHost]?.setEnabled(enabled)
|
preferences[Preferences.Key.ProxyHost]?.setEnabled(enabled)
|
||||||
preferences[Preferences.Key.ProxyPort]?.setEnabled(enabled)
|
preferences[Preferences.Key.ProxyPort]?.setEnabled(enabled)
|
||||||
}
|
}
|
||||||
if (key == Preferences.Key.RootPermission) {
|
if (key == null || key == Preferences.Key.RootPermission) {
|
||||||
preferences[Preferences.Key.RootPermission]?.setEnabled(
|
preferences[Preferences.Key.RootPermission]?.setEnabled(
|
||||||
Shell.getCachedShell()?.isRoot
|
Shell.getCachedShell()?.isRoot
|
||||||
?: Shell.getShell().isRoot
|
?: Shell.getShell().isRoot
|
||||||
)
|
)
|
||||||
|
preferences[Preferences.Key.RootSessionInstaller]?.setEnabled(Utils.rootInstallerEnabled)
|
||||||
}
|
}
|
||||||
if (key == Preferences.Key.Theme) {
|
if (key == Preferences.Key.Theme) {
|
||||||
requireActivity().recreate()
|
requireActivity().recreate()
|
||||||
|
@ -51,6 +51,10 @@ class PrefsUpdatesFragment : PrefsNavFragmentX() {
|
|||||||
Preferences.Key.RootPermission, getString(R.string.root_permission),
|
Preferences.Key.RootPermission, getString(R.string.root_permission),
|
||||||
getString(R.string.root_permission_description)
|
getString(R.string.root_permission_description)
|
||||||
)
|
)
|
||||||
|
addSwitch(
|
||||||
|
Preferences.Key.RootSessionInstaller, getString(R.string.root_session_installer),
|
||||||
|
getString(R.string.root_session_installer_description)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,4 +194,6 @@
|
|||||||
<string name="ignore_battery_optimization_not_supported">The device doesn\'t support ignoring battery optimizations!</string>
|
<string name="ignore_battery_optimization_not_supported">The device doesn\'t support ignoring battery optimizations!</string>
|
||||||
<string name="dialog_refuse">Don\'t need it</string>
|
<string name="dialog_refuse">Don\'t need it</string>
|
||||||
<string name="dialog_approve">Let\'s do it!</string>
|
<string name="dialog_approve">Let\'s do it!</string>
|
||||||
|
<string name="root_session_installer">Use root session installer</string>
|
||||||
|
<string name="root_session_installer_description">The session installer is a bit less performant that the legacy one, but avoids issues with installed apps in Android +13.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user