/system/app 和 /system/priv-app 有什麼區別?

轉載自: https://cn.apkjam.com/system-app.html

關於目錄

/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,實現保活。

關於 System App

在 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 :

  1. 特定 shared uid 的 App
    例如: shared uid 爲 android.uid.systemandroid.uid.phoneandroid.uid.logandroid.uid.nfcandroid.uid.bluetoothandroid.uid.shell。這類 App 都被賦予了 ApplicationInfo.FLAG_SYSTEM 標誌。
  2. 特定目錄中的 App
    特定目錄包括:/vendor/overlay/system/framework/system/priv-app/system/app/vendor/app/oem/app。這些目錄中的 App,被視爲 System App。

關於 Privileged 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 的構造方法

  1. 特定 uid 的 App
    shared uid 爲 android.uid.systemandroid.uid.phoneandroid.uid.logandroid.uid.nfcandroid.uid.bluetoothandroid.uid.shell 的 App 被賦予了 privileged 的權限。這些 App 同時也是 System App。
  2. 特定目錄中的 App
    /system/framework 和 /system/priv-app 目錄下的 App 被賦予了 privileged 的權限。其中 /system/framework 目錄中的 apk,只是包含資源,不包含代碼(dex)。

擴展閱讀:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章