转载自: https://cn.apkjam.com/system-app.html
关于目录关于进程关于 System App关于 Privileged App/system/priv-app 中包括 Launcher,SystemUI, SettingsProvider 等,均是系统的核心应用,这些应用能使用系统级的权限,4.4 之前的所有 /system/app 下的软件都能使用系统级的权限。
Google 这样做是把内置到系统的应用也做个级别的区别。
放到 /system/priv-app 下的应用比放到 /system/app 下的应用可以声明获得更多的权限。
在 Android 中,每个应用都有自己的权限声明,比如要使用系统限制的权限(例如 android.permission.WRITE_SECURE_SETTINGS),我们就需要把程序安装到 /system/app 下。
手机被 root 后,通过 adb push 可以把 apk 推送到这两个目录,作为系统应用,用户无法删除。
从应用的运行角度来说,/system/priv-app 中的 service 是不能被 kill 掉的,就算通过 adb kill 掉后系统也会重新拉起。例如:
1 Line 14879: 09-28 10:07:06.352 1624 2165 W ActivityManager: Scheduling restart of crashed service com.xxx.xxx/.xxx.xxxin 1000ms 2 Line 14907: 09-28 10:07:06.366 1624 2165 I ActivityManager: Start proc 5588:com.xxx.xxx/u0a96 for restart com.xxx.xxx好处是进程可以保持始终运行,并且能拿到最多的权限;坏处是无法正常升级,因为一被 kill 马上又被拉起来,并且升级完成后,再起来的还是旧版本的 service。
所以,我们的应用被预装到终端手机 ROM 中时,为了保活,并且尽量减少终端厂商的工作量,如果能解决升级的问题,对于终端厂商来说就只需要把应用 push 到 /system/priv-app 下就可以了。没有找到解决升级的办法,最终采用的方案往往是 push 到 /system/app,系统通过一个 service(如 phone)来 bind 我们的 service,一旦 disconnect 之后再来 bind,实现保活。
在 PackageManagerService 中对是否是 System App 的判断:
1 private static boolean isSystemApp(PackageParser.Package pkg) { 2 return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 3 } 4 5 private static boolean isSystemApp(PackageSetting ps) { 6 return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0; 7 }具有 ApplicationInfo.FLAG_SYSTEM 标记的,被视为 System App。
有两类 App 属于 System App :
特定 shared uid 的 App 例如: shared uid 为 android.uid.system, android.uid.phone, android.uid.log, android.uid.nfc, android.uid.bluetooth, android.uid.shell。这类 App 都被赋予了 ApplicationInfo.FLAG_SYSTEM 标志。 特定目录中的 App 特定目录包括: /vendor/overlay, /system/framework, /system/priv-app, /system/app, /vendor/app, /oem/app。这些目录中的 App,被视为 System App。Privileged App,即「特权应用」,主要原因是此类特权 App 可以使用 protectionLevel 为 signatureOrSystem 或者 protectionLevel 为 signature|privileged 的权限。
从 PackageManagerService 的 isPrivilegedApp() 可以看出特权 App 是具有 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED 标志的一类 App。
1 private static boolean isPrivilegedApp(PackageParser.Package pkg) { 2 return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0; 3 }特权 App 首先必须是 System App,也就是说 System App 分为普通的 System App 和特权的 System App(System App = 普通 System App + 特权 App)。
直观的(但不准确严谨)说,普通的 System App 就是 /system/app 目录中的 App,特权的 System App 就是 /system/priv-app 目录中的 App(priv-app 是 privileged app 的简写)。
两类 Privileged App
特权 App 首先是 System App,然后要具有 ApplicationInfo.PRIVATE_FLAG_PRIVILEGED 标志。
有两类 App 属于 Privileged App(特权 App):
参考 PackageManagerService 的构造方法
特定 uid 的 App shared uid 为 android.uid.system, android.uid.phone, android.uid.log, android.uid.nfc, android.uid.bluetooth, android.uid.shell 的 App 被赋予了 privileged 的权限。这些 App 同时也是 System App。 特定目录中的 App /system/framework 和 /system/priv-app 目录下的 App 被赋予了 privileged 的权限。其中 /system/framework 目录中的 apk,只是包含资源,不包含代码(dex)。扩展阅读:
Android 4.4 增加的 /system/priv-app 跟原来的 /system/app 有啥区别呢?About /system/priv-app partition