diff --git a/app/core/src/main/java/com/topjohnwu/magisk/test/Environment.kt b/app/core/src/main/java/com/topjohnwu/magisk/test/Environment.kt index 2cd2112ff4f3f..b3a7d57620956 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/test/Environment.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/test/Environment.kt @@ -8,16 +8,16 @@ import androidx.core.net.toUri import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.topjohnwu.magisk.core.BuildConfig.APP_PACKAGE_NAME -import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.di.ServiceLocator import com.topjohnwu.magisk.core.download.DownloadNotifier import com.topjohnwu.magisk.core.download.DownloadProcessor import com.topjohnwu.magisk.core.ktx.cachedFile -import com.topjohnwu.magisk.core.model.su.SuPolicy import com.topjohnwu.magisk.core.tasks.AppMigration import com.topjohnwu.magisk.core.tasks.FlashZip import com.topjohnwu.magisk.core.tasks.MagiskInstaller +import com.topjohnwu.magisk.core.utils.RootUtils import com.topjohnwu.superuser.CallbackList +import com.topjohnwu.superuser.Shell import kotlinx.coroutines.runBlocking import org.junit.Assert.assertTrue import org.junit.Assume.assumeTrue @@ -34,7 +34,11 @@ class Environment { companion object { @BeforeClass @JvmStatic - fun before() = MagiskAppTest.before() + fun before() { + assertTrue("Should have root access", Shell.getShell().isRoot) + // Make sure the root service is running + RootUtils.Connection.await() + } fun lsposed(): Boolean { return Build.VERSION.SDK_INT >= 27 && Build.VERSION.SDK_INT <= 34 @@ -88,23 +92,6 @@ class Environment { } } - @Test - fun setupShellGrantTest() { - runBlocking { - // Inject an undetermined + mute logging policy for ADB shell - val policy = SuPolicy( - uid = 2000, - logging = false, - notification = false, - until = 0L - ) - ServiceLocator.policyDB.update(policy) - // Bypass the need to actually show a dialog - Config.suAutoResponse = Config.Value.SU_AUTO_ALLOW - Config.prefs.edit().commit() - } - } - @Test fun setupAppHide() { runBlocking { diff --git a/app/core/src/main/java/com/topjohnwu/magisk/test/MagiskAppTest.kt b/app/core/src/main/java/com/topjohnwu/magisk/test/MagiskAppTest.kt index 85f9d6e20311c..327085c407218 100644 --- a/app/core/src/main/java/com/topjohnwu/magisk/test/MagiskAppTest.kt +++ b/app/core/src/main/java/com/topjohnwu/magisk/test/MagiskAppTest.kt @@ -1,14 +1,25 @@ package com.topjohnwu.magisk.test +import android.app.Instrumentation +import android.content.Intent +import android.content.IntentFilter import androidx.annotation.Keep import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.topjohnwu.magisk.core.Config import com.topjohnwu.magisk.core.Info -import com.topjohnwu.magisk.core.utils.RootUtils -import com.topjohnwu.superuser.Shell +import com.topjohnwu.magisk.core.di.ServiceLocator +import com.topjohnwu.magisk.core.model.su.SuPolicy +import kotlinx.coroutines.runBlocking +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull import org.junit.Assert.assertTrue +import org.junit.Before import org.junit.BeforeClass import org.junit.Test import org.junit.runner.RunWith +import java.io.FileInputStream +import java.util.concurrent.TimeUnit @RunWith(AndroidJUnit4::class) @Keep @@ -17,15 +28,63 @@ class MagiskAppTest { companion object { @BeforeClass @JvmStatic - fun before() { - assertTrue("Should have root access", Shell.getShell().isRoot) - // Make sure the root service is running - RootUtils.Connection.await() - } + fun before() = Environment.before() + } + + private lateinit var inst: Instrumentation + private val uiAutomation get() = inst.uiAutomation + + @Before + fun setup() { + inst = InstrumentationRegistry.getInstrumentation() } @Test fun testZygisk() { assertTrue("Zygisk should be enabled", Info.isZygiskEnabled) } + + @Test + fun testSuRequest() { + // Bypass the need to actually show a dialog + Config.suAutoResponse = Config.Value.SU_AUTO_ALLOW + Config.prefs.edit().commit() + + // Inject an undetermined + mute logging policy for ADB shell + val policy = SuPolicy( + uid = 2000, + logging = false, + notification = false, + until = 0L + ) + runBlocking { + ServiceLocator.policyDB.update(policy) + } + + val filter = IntentFilter(Intent.ACTION_VIEW) + filter.addCategory(Intent.CATEGORY_DEFAULT) + val monitor = inst.addMonitor(filter, null, false) + + // Try to call su from ADB shell + var pfd = uiAutomation.executeShellCommand("su -c id") + + // Make sure SuRequestActivity is launched + val suRequest = monitor.waitForActivityWithTimeout(TimeUnit.SECONDS.toMillis(10)) + assertNotNull("SuRequestActivity is not launched", suRequest) + + // Check that the request went through + FileInputStream(pfd.fileDescriptor).use { + assertTrue( + "Cannot grant root permission from shell", + it.reader().readText().contains("uid=0") + ) + } + + // Check that the database is updated + runBlocking { + val policy = ServiceLocator.policyDB.fetch(2000) + ?: throw AssertionError("PolicyDB is invalid") + assertEquals("Policy for shell is incorrect", SuPolicy.ALLOW, policy.policy) + } + } } diff --git a/scripts/test_common.sh b/scripts/test_common.sh index 341de8e4ae346..310541b07d84b 100644 --- a/scripts/test_common.sh +++ b/scripts/test_common.sh @@ -67,11 +67,6 @@ run_tests() { # Run app tests am_instrument '.MagiskAppTest,.AdditionalTest' - # Test shell su request - am_instrument '.Environment#setupShellGrantTest' - adb shell /system/xbin/su 2000 su -c id | tee /dev/fd/2 | grep -q 'uid=0' - adb shell am force-stop com.topjohnwu.magisk - # Test app hiding am_instrument '.Environment#setupAppHide' wait_for_pm com.topjohnwu.magisk @@ -79,11 +74,6 @@ run_tests() { # Make sure it still works am_instrument '.MagiskAppTest' true - # Test shell su request - am_instrument '.Environment#setupShellGrantTest' true - adb shell /system/xbin/su 2000 su -c id | tee /dev/fd/2 | grep -q 'uid=0' - adb shell am force-stop repackaged.com.topjohnwu.magisk - # Test app restore am_instrument '.Environment#setupAppRestore' true wait_for_pm repackaged.com.topjohnwu.magisk