mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-08-12 06:37:44 +00:00
Fix systemless hosts installation
This commit is contained in:
@@ -22,11 +22,11 @@ import com.topjohnwu.magisk.core.ktx.activity
|
|||||||
import com.topjohnwu.magisk.core.ktx.toast
|
import com.topjohnwu.magisk.core.ktx.toast
|
||||||
import com.topjohnwu.magisk.core.tasks.AppMigration
|
import com.topjohnwu.magisk.core.tasks.AppMigration
|
||||||
import com.topjohnwu.magisk.core.utils.LocaleSetting
|
import com.topjohnwu.magisk.core.utils.LocaleSetting
|
||||||
|
import com.topjohnwu.magisk.core.utils.RootUtils
|
||||||
import com.topjohnwu.magisk.databinding.bindExtra
|
import com.topjohnwu.magisk.databinding.bindExtra
|
||||||
import com.topjohnwu.magisk.events.AddHomeIconEvent
|
import com.topjohnwu.magisk.events.AddHomeIconEvent
|
||||||
import com.topjohnwu.magisk.events.AuthEvent
|
import com.topjohnwu.magisk.events.AuthEvent
|
||||||
import com.topjohnwu.magisk.events.SnackbarEvent
|
import com.topjohnwu.magisk.events.SnackbarEvent
|
||||||
import com.topjohnwu.superuser.Shell
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
||||||
@@ -130,7 +130,8 @@ class SettingsViewModel : BaseViewModel(), BaseSettingsItem.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createHosts() {
|
private fun createHosts() {
|
||||||
Shell.cmd("add_hosts_module").submit {
|
viewModelScope.launch {
|
||||||
|
RootUtils.addSystemlessHosts()
|
||||||
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
|
AppContext.toast(R.string.settings_hosts_toast, Toast.LENGTH_SHORT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,4 +6,5 @@ package com.topjohnwu.magisk.core.utils;
|
|||||||
interface IRootUtils {
|
interface IRootUtils {
|
||||||
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
|
android.app.ActivityManager.RunningAppProcessInfo getAppProcess(int pid);
|
||||||
IBinder getFileSystem();
|
IBinder getFileSystem();
|
||||||
|
boolean addSystemlessHosts();
|
||||||
}
|
}
|
||||||
|
@@ -109,7 +109,7 @@ fun PackageManager.getPackageInfo(uid: Int, pid: Int): PackageInfo? {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
// Try to find package name from PID
|
// Try to find package name from PID
|
||||||
val proc = RootUtils.obj?.getAppProcess(pid)
|
val proc = RootUtils.getAppProcess(pid)
|
||||||
if (proc == null) {
|
if (proc == null) {
|
||||||
if (uid == Process.SHELL_UID) {
|
if (uid == Process.SHELL_UID) {
|
||||||
// It is possible that some apps installed are sharing UID with shell.
|
// It is possible that some apps installed are sharing UID with shell.
|
||||||
|
@@ -7,11 +7,14 @@ import android.content.ServiceConnection
|
|||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import android.system.Os
|
import android.system.Os
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import com.topjohnwu.magisk.core.Const
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.superuser.Shell
|
import com.topjohnwu.superuser.Shell
|
||||||
import com.topjohnwu.superuser.ShellUtils
|
import com.topjohnwu.superuser.ShellUtils
|
||||||
import com.topjohnwu.superuser.ipc.RootService
|
import com.topjohnwu.superuser.ipc.RootService
|
||||||
import com.topjohnwu.superuser.nio.FileSystemManager
|
import com.topjohnwu.superuser.nio.FileSystemManager
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.locks.AbstractQueuedSynchronizer
|
import java.util.concurrent.locks.AbstractQueuedSynchronizer
|
||||||
@@ -43,16 +46,7 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
return object : IRootUtils.Stub() {
|
return object : IRootUtils.Stub() {
|
||||||
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
|
override fun getAppProcess(pid: Int) = safe(null) { getAppProcessImpl(pid) }
|
||||||
override fun getFileSystem(): IBinder = FileSystemManager.getService()
|
override fun getFileSystem(): IBinder = FileSystemManager.getService()
|
||||||
}
|
override fun addSystemlessHosts() = safe(false) { addSystemlessHostsImpl() }
|
||||||
}
|
|
||||||
|
|
||||||
private inline fun <T> safe(default: T, block: () -> T): T {
|
|
||||||
return try {
|
|
||||||
block()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
// The process died unexpectedly
|
|
||||||
Timber.e(e)
|
|
||||||
default
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +72,26 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addSystemlessHostsImpl(): Boolean {
|
||||||
|
val module = File(Const.MODULE_PATH, "hosts")
|
||||||
|
if (module.exists()) return true
|
||||||
|
val hosts = File(module, "system/etc/hosts")
|
||||||
|
if (!hosts.parentFile.mkdirs()) return false
|
||||||
|
File(module, "module.prop").outputStream().writer().use {
|
||||||
|
it.write("""
|
||||||
|
id=hosts
|
||||||
|
name=Systemless Hosts
|
||||||
|
version=1.0
|
||||||
|
versionCode=1
|
||||||
|
author=Magisk
|
||||||
|
description=Magisk app built-in systemless hosts module
|
||||||
|
""".trimIndent())
|
||||||
|
}
|
||||||
|
File("/system/etc/hosts").copyTo(hosts)
|
||||||
|
File(module, "update").createNewFile()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
object Connection : AbstractQueuedSynchronizer(), ServiceConnection {
|
object Connection : AbstractQueuedSynchronizer(), ServiceConnection {
|
||||||
init {
|
init {
|
||||||
state = 1
|
state = 1
|
||||||
@@ -131,11 +145,25 @@ class RootUtils(stub: Any?) : RootService() {
|
|||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
private set
|
private set
|
||||||
var obj: IRootUtils? = null
|
private var obj: IRootUtils? = null
|
||||||
get() {
|
get() {
|
||||||
Connection.await()
|
Connection.await()
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
private set
|
|
||||||
|
fun getAppProcess(pid: Int) = safe(null) { obj?.getAppProcess(pid) }
|
||||||
|
|
||||||
|
suspend fun addSystemlessHosts() =
|
||||||
|
withContext(Dispatchers.IO) { safe(false) { obj?.addSystemlessHosts() ?: false } }
|
||||||
|
|
||||||
|
private inline fun <T> safe(default: T, block: () -> T): T {
|
||||||
|
return try {
|
||||||
|
block()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
// The process died unexpectedly
|
||||||
|
Timber.e(e)
|
||||||
|
default
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -123,7 +123,9 @@ class Environment : BaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSystemlessHost() {
|
private fun setupSystemlessHost() {
|
||||||
assertTrue("hosts setup failed", Shell.cmd("add_hosts_module").exec().isSuccess)
|
val error = "hosts setup failed"
|
||||||
|
assertTrue(error, runBlocking { RootUtils.addSystemlessHosts() })
|
||||||
|
assertTrue(error, RootUtils.fs.getFile(Const.MODULE_PATH).getChildFile("hosts").exists())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSepolicyRuleModule(root: ExtendedFile) {
|
private fun setupSepolicyRuleModule(root: ExtendedFile) {
|
||||||
|
@@ -118,24 +118,6 @@ EOF
|
|||||||
cd /
|
cd /
|
||||||
}
|
}
|
||||||
|
|
||||||
add_hosts_module() {
|
|
||||||
# Do not touch existing hosts module
|
|
||||||
[ -d /data/adb/modules/hosts ] && return
|
|
||||||
cd /data/adb/modules
|
|
||||||
mkdir -p hosts/system/etc
|
|
||||||
cat << EOF > hosts/module.prop
|
|
||||||
id=hosts
|
|
||||||
name=Systemless Hosts
|
|
||||||
version=1.0
|
|
||||||
versionCode=1
|
|
||||||
author=Magisk
|
|
||||||
description=Magisk app built-in systemless hosts module
|
|
||||||
EOF
|
|
||||||
magisk --clone /system/etc/hosts hosts/system/etc/hosts
|
|
||||||
touch hosts/update
|
|
||||||
cd /
|
|
||||||
}
|
|
||||||
|
|
||||||
# $1 = APK
|
# $1 = APK
|
||||||
# $2 = package name
|
# $2 = package name
|
||||||
adb_pm_install() {
|
adb_pm_install() {
|
||||||
|
Reference in New Issue
Block a user