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