当前位置:编程学习 > 网站相关 >>

android安全问题(七) 抢先接收广播 - 内因篇之广播发送流程

导读:本文说明系统发送广播的部分流程,如何利用Intent查找到对应接收器。我们依然只关注接收器的排序问题
 
 
 
 
这篇文章主要是针对我前两篇文章
android安全问题(五) 抢先拦截短信 - 结果篇
android安全问题(四) 抢先开机启动 - 结果篇
 
现在给出第二步分的分析
 
 
 
 
 
下面就来看看发送广播的流程
 
Context中的sendBroadCast函数的实现是在ContextImpl中,和发送广播相关的有如下六个函数
 
void android.app.ContextImpl.sendBroadcast(Intent intent)
 
void android.app.ContextImpl.sendBroadcast(Intent intent, String receiverPermission)
 
void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission)
 
void android.app.ContextImpl.sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
 
void android.app.ContextImpl.sendStickyBroadcast(Intent intent)
 
void android.app.ContextImpl.sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)
 
 
 
可以分为3组:1普通广播;2Ordered广播;3Sticky广播
 
不论哪种,最后都会由ActivityManagerService处理
 
private final int broadcastIntentLocked(ProcessRecord callerApp,  
        String callerPackage, Intent intent, String resolvedType,  
        IIntentReceiver resultTo, int resultCode, String resultData,  
        Bundle map, String requiredPermission,  
        boolean ordered, boolean sticky, int callingPid, int callingUid)  
 
private final int broadcastIntentLocked(ProcessRecord callerApp,
        String callerPackage, Intent intent, String resolvedType,
        IIntentReceiver resultTo, int resultCode, String resultData,
        Bundle map, String requiredPermission,
        boolean ordered, boolean sticky, int callingPid, int callingUid)以第一种情况为例,流程图大概是这个样子的
 
\
 
 
ordered和sticky用来区分上面3组广播
 
下面我们仔细看看这个方法都干了些什么
 
删减了一些代码
 
private final int broadcastIntentLocked(ProcessRecord callerApp,  
        String callerPackage, Intent intent, String resolvedType,  
        IIntentReceiver resultTo, int resultCode, String resultData,  
        Bundle map, String requiredPermission,  
        boolean ordered, boolean sticky, int callingPid, int callingUid) {  
    ...//处理特殊intent   
    // Add to the sticky list if requested.   
    ...//处理sticky广播   
    // Figure out who all will receive this broadcast.   
    List receivers = null;  
    List registeredReceivers = null;  
    try {  
        if (intent.getComponent() != null) {  
            // Broadcast is going to one specific receiver class...   
            ActivityInfo ai = AppGlobals.getPackageManager().  
                getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);  
            if (ai != null) {  
                receivers = new ArrayList();  
                ResolveInfo ri = new ResolveInfo();  
                ri.activityInfo = ai;  
                receivers.add(ri);  
            }  
        } else {  
            // Need to resolve the intent to interested receivers...   
            if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)  
                     == 0) {  
                receivers =  
                    AppGlobals.getPackageManager().queryIntentReceivers(  
                            intent, resolvedType, STOCK_PM_FLAGS);  
            }  
            registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);  
        }  
    } catch (RemoteException ex) {  
        // pm is in same process, this will never happen.   
    }  
  
    final boolean replacePending =  
            (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;  
    ...  
    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;  
    ...//如果广播是非ordered,先处理动态注册的接收器   
    if (!ordered && NR > 0) {  
        // If we are not serializing this broadcast, then send the   
        // registered receivers separately so they don't wait for the   
        // components to be launched.   
        BroadcastRecord r = new BroadcastRecord(intent, callerApp,  
                callerPackage, callingPid, callingUid, requiredPermission,  
                registeredReceivers, resultTo, resultCode, resultData, map,  
                ordered, sticky, false);  
        ...  
    //mParallelBroadcasts只含有动态注册的receiver   
        boolean replaced = false;  
        if (replacePending) {  
            for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {  
                if (intent.filterEquals(mParallelBroadcasts.get(i).intent)
补充:综合编程 , 安全编程 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,