在閱讀Android源碼Telephony 模塊時,,發(fā)現(xiàn)在AndroidManifest.xml 文件里聲明了大量的protected-broadcast :
<protected-broadcast android:name= 'android.intent.action.DATA_SMS_RECEIVED' />
<protected-broadcast android:name= 'android.provider.Telephony.SMS_RECEIVED' />
...
聲明的都是一些廣播action,比如新短信到達(dá)的廣播'android.provider.Telephony.SMS_RECEIVED' ,,顯然這些廣播action 都是很重要的廣播,,并不能隨隨便便發(fā)送,,所以android就做了限制。而直接從protected-broadcast字面意思來看,,是受保護(hù)的廣播 ,,確實(shí)也是如此:
protected-broadcast 用來指定一個廣播,該廣播只能被系統(tǒng)發(fā)送,,如果普通APP在自己的xml里聲明了這些廣播,,發(fā)送時也會被提示錯誤。'Permission Denial: not allowed to send broadcast'
那么誰有權(quán)限來發(fā)送這些廣播呢,?也就是說所謂的系統(tǒng)APP都有哪些呢,?
這里直接說結(jié)論:
發(fā)送廣播最終都會通過AMS (ActivityManagerService)來發(fā)送,而在最終調(diào)用里,,會看到有關(guān)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就是各進(jìn)程的身份標(biāo)識,程序一運(yùn)行系統(tǒng)就會自動分配給進(jìn)程一個獨(dú)一無二的PID,。linux中進(jìn)程中止后PID被系統(tǒng)回收,,可能會被繼續(xù)分配給新運(yùn)行的程序,但是在android系統(tǒng)中一般不會把已經(jīng)kill掉的進(jìn)程ID重新分配給新的進(jìn)程,,新產(chǎn)生進(jìn)程的進(jìn)程號,,一般比產(chǎn)生之前所有的進(jìn)程號都要大。
UID:一般理解為User Identifier,UID在linux中就是用戶的ID,,表明時哪個用戶運(yùn)行了這個程序,,主要用于權(quán)限的管理。而在android 中又有所不同,,除了進(jìn)行權(quán)限控制之外,,Android還使用它來進(jìn)行一些數(shù)據(jù)的共享,這也就是在AndroidManifest.xml 里使用android:sharedUserId 的作用,,使用同一個sharedUserId 的兩個不同APP,,可以運(yùn)行在同一個進(jìn)程,并且可以相互訪問數(shù)據(jù),。而普通的兩個不同APP,,是不能隨意相互訪問數(shù)據(jù)的,只能通過跨進(jìn)程訪問,。
如果連接真機(jī)通過ps 命令查看所有進(jìn)程,,可以看到第一列是user ,這就是UID 的描述
|