Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ dependencies {
implementation 'dev.chrisbanes:insetter-ktx:0.3.1'
implementation 'dev.rikka.rikkax.preference:simplemenu-preference:1.0.3'
implementation 'dev.rikka.shizuku:api:13.1.5'
implementation 'dev.rikka.shizuku:provider:13.1.5'
implementation ('eu.agno3.jcifs:jcifs-ng:2.1.10') {
exclude group: 'org.bouncycastle', module: 'bcprov-jdk18on'
}
Expand Down
10 changes: 9 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

<!-- Crashlytics and Shizuku requires API 23. -->
<uses-sdk tools:overrideLibrary="com.google.firebase,com.google.firebase.components,com.google.firebase.crashlytics,com.google.firebase.crashlytics.ndk,com.google.firebase.installations,com.google.firebase.sessions,rikka.shizuku.aidl,rikka.shizuku.api,rikka.shizuku.shared" />
<uses-sdk tools:overrideLibrary="com.google.firebase,com.google.firebase.components,com.google.firebase.crashlytics,com.google.firebase.crashlytics.ndk,com.google.firebase.installations,com.google.firebase.sessions,rikka.shizuku.aidl,rikka.shizuku.api,rikka.shizuku.shared,rikka.shizuku.provider" />

<!--
~ Samsung DeX requires explicitly setting android:resizeableActivity="true" for the app to be

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tools:overrideLibrary="rikka.shizuku.aidl,rikka.shizuku.api,rikka.shizuku.shared

Expand Down Expand Up @@ -389,6 +389,14 @@
android:exported="false"
android:grantUriPermissions="true" />

<provider
android:name="rikka.shizuku.ShizukuProvider"
android:authorities="${applicationId}.shizuku"
android:multiprocess="false"
android:enabled="true"
android:exported="true"
android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />

<receiver android:name="me.zhanghai.android.files.filejob.FileJobReceiver" />

<receiver android:name="me.zhanghai.android.files.ftpserver.FtpServerReceiver" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ lateinit var rootContext: Context private set

object RootFileService : RemoteFileService(
RemoteInterface {
if (SuiFileServiceLauncher.isSuiAvailable()) {
SuiFileServiceLauncher.launchService()
if (ShizukuFileServiceLauncher.isShizukuAvailable()) {
ShizukuFileServiceLauncher.launchService()
} else {
LibSuFileServiceLauncher.launchService()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,28 @@ import me.zhanghai.android.files.provider.remote.IRemoteFileService
import me.zhanghai.android.files.provider.remote.RemoteFileServiceInterface
import me.zhanghai.android.files.provider.remote.RemoteFileSystemException
import rikka.shizuku.Shizuku
import rikka.sui.Sui
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

object SuiFileServiceLauncher {
object ShizukuFileServiceLauncher {
private val lock = Any()

private var isSuiIntialized = false

@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.M)
fun isSuiAvailable(): Boolean {
fun isShizukuAvailable(): Boolean {
synchronized(lock) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return false
}
if (!isSuiIntialized) {
Sui.init(application.packageName)
isSuiIntialized = true
}
return Sui.isSui()
return Shizuku.pingBinder()
}
}

@RequiresApi(Build.VERSION_CODES.M)
@Throws(RemoteFileSystemException::class)
fun launchService(): IRemoteFileService {
synchronized(lock) {
if (!isSuiAvailable()) {
throw RemoteFileSystemException("Sui isn't available")
if (!isShizukuAvailable()) {
throw RemoteFileSystemException("Shizuku isn't available")
}
if (Shizuku.checkSelfPermission() != PackageManager.PERMISSION_GRANTED) {
val granted = try {
Expand All @@ -78,7 +71,7 @@ object SuiFileServiceLauncher {
throw RemoteFileSystemException(e)
}
if (!granted) {
throw RemoteFileSystemException("Sui permission isn't granted")
throw RemoteFileSystemException("Shizuku permission isn't granted")
}
}
return try {
Expand All @@ -87,11 +80,11 @@ object SuiFileServiceLauncher {
withTimeout(RootFileService.TIMEOUT_MILLIS) {
suspendCancellableCoroutine { continuation ->
val serviceArgs = Shizuku.UserServiceArgs(
ComponentName(application, SuiFileServiceInterface::class.java)
ComponentName(application, ShizukuFileServiceInterface::class.java)
)
.debuggable(BuildConfig.DEBUG)
.daemon(false)
.processNameSuffix("sui")
.processNameSuffix("shizuku")
.version(BuildConfig.VERSION_CODE)
val connection = object : ServiceConnection {
override fun onServiceConnected(
Expand All @@ -107,7 +100,7 @@ object SuiFileServiceLauncher {
if (continuation.isActive) {
continuation.resumeWithException(
RemoteFileSystemException(
"Sui service disconnected"
"Shizuku service disconnected"
)
)
}
Expand All @@ -116,15 +109,15 @@ object SuiFileServiceLauncher {
override fun onBindingDied(name: ComponentName) {
if (continuation.isActive) {
continuation.resumeWithException(
RemoteFileSystemException("Sui binding died")
RemoteFileSystemException("Shizuku binding died")
)
}
}

override fun onNullBinding(name: ComponentName) {
if (continuation.isActive) {
continuation.resumeWithException(
RemoteFileSystemException("Sui binding is null")
RemoteFileSystemException("Shizuku binding is null")
)
}
}
Expand All @@ -148,7 +141,7 @@ object SuiFileServiceLauncher {

@Keep
@RequiresApi(Build.VERSION_CODES.M)
class SuiFileServiceInterface : RemoteFileServiceInterface() {
class ShizukuFileServiceInterface : RemoteFileServiceInterface() {
init {
RootFileService.main()
}
Expand Down