android安全問題(七) 搶先接收廣播

來源:互聯網
上載者:User

現在給出第二步分的分析

下面就來看看發送廣播的流程

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)

以第一種情況為 例,流程圖大概是這個樣子的

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<BroadcastFilter> 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)) {                      if (DEBUG_BROADCAST) Slog.v(TAG,                              "***** DROPPING PARALLEL: " + intent);                      mParallelBroadcasts.set(i, r);                      replaced = true;                      break;                  }              }          }          if (!replaced) {              mParallelBroadcasts.add(r);              scheduleBroadcastsLocked();          }          registeredReceivers = null;          NR = 0;      }            // Merge into one list.      //如果廣播是ordered,合并靜態、動態接收器      //否則之前處理過動態接收器,這裡registeredReceivers為null      int ir = 0;      if (receivers != null) {          ...          //合并的過程,注意順序          int NT = receivers != null ? receivers.size() : 0;          int it = 0;          ResolveInfo curt = null;          BroadcastFilter curr = null;          while (it < NT && ir < NR) {              if (curt == null) {                  curt = (ResolveInfo)receivers.get(it);              }              if (curr == null) {                  curr = registeredReceivers.get(ir);              }              //如果動態接收器優先順序高,那麼就插到前面              //否則進入else,然後進行下一輪比較,拿下一個靜態接收器與之前的動態接收器比較,直到找到自己的位置才插入進列表中              //在這裡,調整好接收器的順序,同等優先順序的,顯然動態要在靜態前面              if (curr.getPriority() >= curt.priority) {                  // Insert this broadcast record into the final list.                  receivers.add(it, curr);                  ir++;                  curr = null;                  it++;                  NT++;              } else {                  // Skip to the next ResolveInfo in the final list.                  it++;                  curt = null;              }          }      }      while (ir < NR) {          if (receivers == null) {              receivers = new ArrayList();          }          receivers.add(registeredReceivers.get(ir));          ir++;      }            if ((receivers != null && receivers.size() > 0)              || resultTo != null) {          BroadcastRecord r = new BroadcastRecord(intent, callerApp,                  callerPackage, callingPid, callingUid, requiredPermission,                  receivers, resultTo, resultCode, resultData, map, ordered,                  sticky, false);          ...          if (!replaced) {              mOrderedBroadcasts.add(r);              scheduleBroadcastsLocked();          }      }            return BROADCAST_SUCCESS;  }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.