InstallerX黑科技:Dhizuku/Shizuku权限管理深度剖析

InstallerX黑科技:Dhizuku/Shizuku权限管理深度剖析

【免费下载链接】InstallerX A modern and functional Android app installer. (You know some birds are not meant to be caged, their feathers are just too bright.) 【免费下载链接】InstallerX 项目地址: https://gitcode.com/GitHub_Trending/ins/InstallerX

你是否还在为Android应用安装时频繁的权限弹窗烦恼?是否希望拥有更灵活的应用安装控制方式?InstallerX作为一款现代化的Android应用安装器,通过集成Dhizuku和Shizuku权限管理框架,为用户带来了革命性的权限管理体验。本文将深入剖析InstallerX中Dhizuku和Shizuku权限管理的实现原理,帮助你彻底搞懂这两项黑科技。

权限管理框架概述

InstallerX通过Dhizuku和Shizuku两种权限管理框架,实现了对Android系统级权限的精细化控制。这两种框架均基于Android的Binder机制,允许应用在不获取Root权限的情况下,通过特定的服务接口获取更高的系统权限,从而实现更强大的应用安装功能。

在InstallerX的架构中,权限管理模块主要集中在app/src/main/java/com/rosan/installer/data/recycle/目录下。其中,Dhizuku相关的实现包括DhizukuPrivilegedService.ktDhizukuUtil.kt,而Shizuku相关的实现则位于ShizukuUserServiceRecycler.ktShizukuUtil.kt

Dhizuku权限管理深度剖析

Dhizuku是一种基于Android设备所有者(Device Owner)机制的权限管理框架。通过Dhizuku,InstallerX可以获取设备所有者权限,从而实现对应用安装过程的深度控制。

Dhizuku权限获取流程

InstallerX通过DhizukuUtil.kt中的requireDhizukuPermissionGranted函数来获取Dhizuku权限。该函数的实现如下:

suspend fun <T> requireDhizukuPermissionGranted(action: suspend () -> T): T {
    callbackFlow {
        Dhizuku.init()
        if (Dhizuku.isPermissionGranted()) send(Unit)
        else {
            Dhizuku.requestPermission(object : DhizukuRequestPermissionListener() {
                override fun onRequestPermission(grantResult: Int) {
                    if (grantResult == PackageManager.PERMISSION_GRANTED) trySend(Unit)
                    else close(Exception("dhizuku permission denied"))
                }
            })
        }
        awaitClose()
    }.catch {
        throw DhizukuNotWorkException(it)
    }.first()
    return action()
}

该函数首先初始化Dhizuku,然后检查是否已经获取权限。如果尚未获取,则通过Dhizuku.requestPermission方法请求权限。如果权限请求被拒绝,则抛出DhizukuNotWorkException.kt异常。

Dhizuku权限应用场景

获取Dhizuku权限后,InstallerX通过DhizukuPrivilegedService.kt实现了多种高级权限操作,包括:

  1. 设置默认安装器:通过setDefaultInstaller方法,将InstallerX设置为系统默认的应用安装器。
  2. 授予运行时权限:通过grantRuntimePermission方法,为应用授予运行时权限,无需用户手动确认。
  3. 检查权限状态:通过isPermissionGranted方法,检查特定权限是否已授予。

以授予运行时权限为例,DhizukuPrivilegedService.kt中的实现如下:

override fun grantRuntimePermission(packageName: String, permission: String) {
    if (packageName.isEmpty() || permission.isEmpty()) {
        Timber.tag("DhizukuPrivilegedService")
            .w("grantRuntimePermission called with invalid arguments: packageName=$packageName, permission=$permission")
        throw IllegalArgumentException("packageName and permission must not be empty.")
    }

    try {
        val ownerComponent = Dhizuku.getOwnerComponent()
        Timber.tag("DhizukuPrivilegedService")
            .d("Attempting to grant permission '$permission' to package '$packageName' using owner '$ownerComponent'")

        devicePolicyManager.setPermissionGrantState(
            ownerComponent,
            packageName,
            permission,
            DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED
        )
        Timber.tag("DhizukuPrivilegedService")
            .i("Successfully granted permission '$permission' to package '$packageName'")
    } catch (t: Throwable) {
        Timber.tag("DhizukuPrivilegedService")
            .e(t, "Failed to grant permission '$permission' to package '$packageName'")
        throw t
    }
}

Shizuku权限管理深度剖析

Shizuku是一种基于Android Binder机制的权限管理框架。与Dhizuku不同,Shizuku不需要设备所有者权限,而是通过与系统服务直接通信来获取更高的权限。

Shizuku权限获取流程

InstallerX通过ShizukuUtil.kt中的requireShizukuPermissionGranted函数来获取Shizuku权限。该函数的实现如下:

suspend fun <T> requireShizukuPermissionGranted(action: suspend () -> T): T {
    callbackFlow {
        Sui.init(BuildConfig.APPLICATION_ID)
        if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED) {
            send(Unit)
            awaitClose()
        } else {
            val requestCode = (Int.MIN_VALUE..Int.MAX_VALUE).random()
            val listener =
                Shizuku.OnRequestPermissionResultListener { _requestCode, grantResult ->
                    if (_requestCode != requestCode) return@OnRequestPermissionResultListener
                    if (Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED)
                        trySend(Unit)
                    else close(Exception("sui/shizuku permission denied"))
                }
            Shizuku.addRequestPermissionResultListener(listener)
            Shizuku.requestPermission(requestCode)
            awaitClose { Shizuku.removeRequestPermissionResultListener(listener) }
        }
    }.catch {
        throw ShizukuNotWorkException(it)
    }.first()
    return action()
}

Shizuku权限应用场景

获取Shizuku权限后,InstallerX通过ShizukuUserServiceRecycler.kt实现了系统级上下文的创建。该功能的核心代码如下:

private fun createSystemContext(fallbackContext: Context): Context {
    try {
        // Get system context
        val activityThreadClass = Class.forName("android.app.ActivityThread")
        val systemMain = activityThreadClass.getMethod("systemMain").invoke(null)
        val systemContext = activityThreadClass.getMethod("getSystemContext").invoke(systemMain) as Context

        val userId = try {
            UserHandle::class.java.getMethod("myUserId").invoke(null) as Int
        } catch (e: Exception) {
            Timber.tag("ShizukuUserService").e(e, "Failed to get userId")
            Process.myUid() / 100000
        }

        val userHandle = Class.forName("android.os.UserHandle")
        val userHandleConstructor = userHandle.getConstructor(Int::class.java)
        val userHandleInstance = userHandleConstructor.newInstance(userId)

        val context = systemContext.javaClass.getMethod(
            "createPackageContextAsUser",
            String::class.java,
            Int::class.java,
            userHandle
        ).invoke(
            systemContext,
            "com.android.shell",
            Context.CONTEXT_INCLUDE_CODE or Context.CONTEXT_IGNORE_SECURITY,
            userHandleInstance
        ) as Context

        val finalContext = context.createPackageContext("com.android.shell", 0)
        Timber.tag("ShizukuUserService").d("Created system context: ${finalContext.packageName}, UID: ${Process.myUid()}")
        return finalContext
    } catch (e: Exception) {
        Timber.tag("ShizukuUserService").e(e, "Failed to create system context: ${e.message}")
        Timber.tag("ShizukuUserService").d("Falling back to app context: ${fallbackContext.packageName}")
        return fallbackContext
    }
}

通过创建系统级上下文,InstallerX可以模拟系统进程的行为,从而实现对应用安装过程的深度控制。

权限管理框架对比分析

Dhizuku和Shizuku作为两种不同的权限管理框架,各有其优缺点和适用场景。下面通过一个表格对它们进行全面对比:

特性DhizukuShizuku
权限级别设备所有者权限系统服务权限
适用设备已设置设备所有者的设备所有支持Shizuku的设备
权限获取难度较高,需要设置设备所有者较低,通过Shizuku Manager授权
功能覆盖范围主要覆盖应用安装相关权限覆盖更广泛的系统级权限
稳定性
兼容性Android 5.0+Android 8.0+

在InstallerX中,Dhizuku和Shizuku并不是互斥的,而是相辅相成。通过在不同场景下选择合适的权限管理框架,InstallerX实现了对应用安装过程的全方位控制。

权限管理的安全性考量

虽然Dhizuku和Shizuku为InstallerX带来了强大的权限管理能力,但同时也带来了一定的安全风险。为了确保系统安全,InstallerX在权限管理模块中加入了多重安全防护措施。

例如,在DhizukuPrivilegedService.ktgrantRuntimePermission方法中,首先对输入参数进行了严格校验:

if (packageName.isEmpty() || permission.isEmpty()) {
    Timber.tag("DhizukuPrivilegedService")
        .w("grantRuntimePermission called with invalid arguments: packageName=$packageName, permission=$permission")
    throw IllegalArgumentException("packageName and permission must not be empty.")
}

此外,InstallerX的AndroidManifest.xml文件中声明了必要的权限和服务,确保权限的获取和使用符合Android系统规范:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />

<service
    android:name="com.rosan.installer.data.installer.model.impl.InstallerService"
    android:permission="android.permission.FOREGROUND_SERVICE"
    android:foregroundServiceType="dataSync" />

总结与展望

通过对InstallerX中Dhizuku和Shizuku权限管理的深度剖析,我们可以看到InstallerX如何通过这两项黑科技实现了对Android应用安装过程的精细化控制。Dhizuku提供了设备所有者级别的安装权限管理,而Shizuku则通过系统服务接口实现了更广泛的系统级权限控制。

未来,随着Android系统的不断演进,InstallerX的权限管理模块也将持续优化。我们有理由相信,InstallerX将继续引领Android应用安装器的技术创新,为用户带来更加安全、高效、便捷的应用安装体验。

官方文档:docs/README.md 权限管理源码:app/src/main/java/com/rosan/installer/data/recycle/ 应用清单配置:app/src/main/AndroidManifest.xml

【免费下载链接】InstallerX A modern and functional Android app installer. (You know some birds are not meant to be caged, their feathers are just too bright.) 【免费下载链接】InstallerX 项目地址: https://gitcode.com/GitHub_Trending/ins/InstallerX

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值