privatevoidcheckBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
String callerPackage,int callingUid,boolean isProtectedBroadcast, List receivers){//如果FLAG 是FLAG_RECEIVER_FROM_SHELL 就没问题,直接返回if((intent.getFlags()& Intent.FLAG_RECEIVER_FROM_SHELL)!=0){// Don't yell about broadcasts sent via shellreturn;}//如果broadcast 的aciton isProtected 或者是这些固定的系统广播,就满足条件final String action = intent.getAction();if(isProtectedBroadcast
|| Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)|| Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)|| Intent.ACTION_MEDIA_BUTTON.equals(action)|| Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)|| Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)|| Intent.ACTION_MASTER_CLEAR.equals(action)|| Intent.ACTION_FACTORY_RESET.equals(action)|| AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)|| LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)|| TelephonyManager.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)|| SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)|| AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)|| AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)){// Broadcast is either protected, or it's a public action that// we've relaxed, so it's fine for system internals to send.return;}//如果指定了 package 或者 component 就去动态注册的广播中筛选// This broadcast may be a problem... but there are often system components that// want to send an internal broadcast to themselves, which is annoying to have to// explicitly list each action as a protected broadcast, so we will check for that// one safe case and allow it: an explicit broadcast, only being received by something// that has protected itself.if(intent.getPackage()!= null || intent.getComponent()!= null){if(receivers == null || receivers.size()==0){// Intent is explicit and there's no receivers.// This happens, e.g. , when a system component sends a broadcast to// its own runtime receiver, and there's no manifest receivers for it,// because this method is called twice for each broadcast,// for runtime receivers and manifest receivers and the later check would find// no receivers.return;}boolean allProtected =true;for(int i = receivers.size()-1; i >=0; i--){
Object target = receivers.get(i);if(target instanceofResolveInfo){
ResolveInfo ri =(ResolveInfo)target;if(ri.activityInfo.exported && ri.activityInfo.permission == null){
allProtected =false;break;}}else{
BroadcastFilter bf =(BroadcastFilter)target;if(bf.requiredPermission == null){
allProtected =false;break;}}}if(allProtected){// All safe!return;}}//到最后所有条件都 不满足,就抛出异常// The vast majority of broadcasts sent from system internals// should be protected to avoid security holes, so yell loudly// to ensure we examine these cases.if(callerApp != null){
Log.wtf(TAG,"Sending non-protected broadcast "+ action
+" from system "+ callerApp.toShortString()+" pkg "+ callerPackage,newThrowable());}else{
Log.wtf(TAG,"Sending non-protected broadcast "+ action
+" from system uid "+ UserHandle.formatUid(callingUid)+" pkg "+ callerPackage,newThrowable());}}