在阅读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
的描述