11.25 安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

簡介

Android系統越來越安全的同時,系統也越來越複雜。5.x以前(包括5.x)應用程序需要的權限,寫入AndroidManifest.xml配置文件,即可。從6.0開始出現了運行時權限檢查的概念,運行時權限要在代碼裡面去主動申請。

從此,Android系統的權限分為安裝權限(install permission)和運行時權限(runtime permission)。安裝權限在AndroidManifest.xml清單文件中進行配置。運行時權限需要在代碼裡面動態申請。

應用層

舉個例子:我要做個通訊錄/電話本。通訊錄需要讀取系統的聯繫人信息,然後進行顯示。Android系統要求:讀取系統聯繫人信息,必須要申請READ_CONTACTS權限。在用戶授權之後,才可以去讀取聯繫人信息。我們分別看一下5.x以前和6.x以後,是怎樣申請權限的?

1. 5.x以前

安卓系統權限檢查機制,存儲位置,數據結構

在5.x(包括5.x)以前,只需要在應用程序的AndroidManifest.xml文件,加入上面這句,就可以了。

用戶在安裝這個應用程序的時候,會在安裝界面上顯示,應用程序申請的權限,用戶可以進行權限管理,然後開始安裝。應用程序在運行的時候,有讀取聯繫人的權限就可以運行成功,否則就會失敗,開發者不能在運行階段去申請權限。

2. 6.x以後

READ_CONTACTS是運行時權限。

安卓系統權限檢查機制,存儲位置,數據結構

這是Google官網,發佈Android 6.0的時候,對版本新特性的介紹。

主要從用戶和開發者的角度來對運行時權限進行介紹。用戶可以在應用程序運行的時候,管理應用權限,對權限進行授權或撤銷。用戶可以更好的瞭解和控制權限。同時,為應用開發者精簡了安裝和自動更新過程。

通過checkSelfPermission()檢查權限,通過requestPermissions()請求權限。

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

首先檢查,本應用是否已經獲得了讀取通訊錄的權限。如果沒有獲得權限,就去主動申請權限。系統會回調onRequestPermissionsResult()方法,來通知應用程序用戶是否授權。

系統層

本節從系統源碼的角度,去看一下下層的設計和實現邏輯。

我們先看看checkSelfPermission()的實現邏輯。

Frameworks/base/core/java/android/app/ContextImpl.java

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

Frameworks/base/core/java/android/app/ActivityManagerNative.java

安卓系統權限檢查機制,存儲位置,數據結構

Binder IPC,下面會調用到AMS裡面去。

Frameworks/base/services/core/java/com/android/server/ActivityManagerService.java

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

Frameworks/base/core/java/android/app/ActivityManager.java

安卓系統權限檢查機制,存儲位置,數據結構

這裡又一次進行Binder通訊,調用到PMS。

Frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

安卓系統權限檢查機制,存儲位置,數據結構

permissionsState裡面存儲著從packages.xml讀取的系統授權信息,通過調用hasPermission()獲取uid是否有permName的授權。

授權數據是保存在文件裡面/data/system/packages.xml。程序運行過程中存儲授權數據的數據結構在下面的類:

frameworks/base/services/core/java/com/android/server/pm/PermissionsState.java

安卓系統權限檢查機制,存儲位置,數據結構

PermissionsState的內部類PermissionState。一個三個變量mFlags暫不清楚有啥作用,mName存儲權限的名字,mGranted標示這個權限是否被授權。這裡是最小的數據單元。

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

PermissionData也是PermissionsState的內部類,用來存儲所有uid的某一權限的授權數據。這裡用到一個數據結構SparseArray,也是用來存儲key-value,不過key只能是int或long。這是一個雙數組結構,一個數組用來存儲key,一個數組用來存儲value,通過兩個數組的下標進行key-value的對應。

安卓系統權限檢查機制,存儲位置,數據結構

PermissonsState類裡面的ArrayMap的數據結構存放著系統所有的權限數據。ArrayMap是一個特殊實現的哈希表,存放的也是key-value。每一個權限,對應一個PermissionData。

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

安卓系統權限檢查機制,存儲位置,數據結構

總結一下,授權數據存放涉及到的數據結構,就是上面這三個截圖。mPermissions是一個特殊的哈希表,裡面存放著系統所有的授權數據,每個權限對應一個PermissionData。mUserStates是一個雙數組,存放的也是key-value,存放uid和對應的授權數據,uid對應一個PermissionState。PermissionState是一個元數據類,存放一個權限的授權狀態。


分享到:


相關文章: