在閱讀Android源碼Telephony
模塊時,發現在AndroidManifest.xml
文件裏聲明瞭大量的protected-broadcast
:
<protected-broadcast android:name=
"android.intent.action.DATA_SMS_RECEIVED" />
<protected-broadcast android:name=
"android.provider.Telephony.SMS_RECEIVED" />
...
聲明的都是一些廣播action,比如新短信到達的廣播"android.provider.Telephony.SMS_RECEIVED"
,顯然這些廣播action
都是很重要的廣播,並不能隨隨便便發送,所以android就做了限制。而直接從protected-broadcast字面意思來看,是受保護的廣播
,確實也是如此:
protected-broadcast
用來指定一個廣播,該廣播只能被系統發送,如果普通APP在自己的xml裏聲明瞭這些廣播,發送時也會被提示錯誤。"Permission Denial: not allowed to send broadcast"
那麼誰有權限來發送這些廣播呢?也就是說所謂的系統APP都有哪些呢?
這裏直接說結論:
發送廣播最終都會通過AMS
(ActivityManagerService)來發送,而在最終調用裏,會看到有關protected-broadcast
的判斷
/*
* Prevent non-system code (defined here to be non-persistent
* processes) from sending protected broadcasts.
*/
int callingAppId = UserHandle.getAppId(callingUid);
if (callingAppId == Process.SYSTEM_UID
||callingAppId == Process.PHONE_UID
||callingAppId == Process.SHELL_UID
||callingAppId == Process.BLUETOOTH_UID
||callingAppId == Process.NFC_UID
||callingUid == 0) {
// Always okay.
} else {
..........
}
所以可以看出是通過UID
來過濾的,SYSTEM_UID
,PHONE_UID
,SHELL_UID
,BLUETOOTH_UID
,NFC_UID
,以及root
(uid
== 0).
/**
* Defines the root UID.
* @hide
*/
public static final int ROOT_UID = 0;
/**
* Defines the UID/GID under which system code runs.
*/
public static final int SYSTEM_UID = 1000;
/**
* Defines the UID/GID under which the telephony code runs.
*/
public static final int PHONE_UID = 1001;
/**
* Defines the UID/GID for the user shell.
* @hide
*/
public static final int SHELL_UID = 2000;
/**
* Defines the UID/GID for the log group.
* @hide
*/
public static final int LOG_UID = 1007;
PID 和 UID
PID:爲Process Identifier,PID就是各進程的身份標識,程序一運行系統就會自動分配給進程一個獨一無二的PID。linux中進程中止後PID被系統回收,可能會被繼續分配給新運行的程序,但是在android系統中一般不會把已經kill掉的進程ID重新分配給新的進程,新產生進程的進程號,一般比產生之前所有的進程號都要大。
UID:一般理解爲User Identifier,UID在linux中就是用戶的ID,表明時哪個用戶運行了這個程序,主要用於權限的管理。而在android 中又有所不同,除了進行權限控制之外,Android還使用它來進行一些數據的共享,這也就是在AndroidManifest.xml
裏使用android:sharedUserId
的作用,使用同一個sharedUserId
的兩個不同APP,可以運行在同一個進程,並且可以相互訪問數據。而普通的兩個不同APP,是不能隨意相互訪問數據的,只能通過跨進程訪問。
如果連接真機通過ps
命令查看所有進程,可以看到第一列是user
,這就是UID
的描述