它们都是调用AMS的broadcastIntentWithFeature来发送广播
如下面是最简单的只有一个Intent的广播发送
//ContextImpl.java
@Override
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
//调用的是AMS的broadcastIntentWithFeature来发送广播
ActivityManager.getService().broadcastIntentWithFeature(
mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
AppOpsManager.OP_NONE, null, false, false, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
//Notifier.java
private final Intent mScreenOnIntent;
//新建一个Intent,它的action是ACTION_SCREEN_ON,
//注意此处增加了
//FLAG_RECEIVER_REGISTERED_ONLY: 只允许动态注册的接收者接受
//FLAG_RECEIVER_FOREGROUND: 前台接收,也就是前台广播(10s超时)的队列
//FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS: 可以被即时app接收
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
mScreenOnIntent.addFlags(
Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
| Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
//亮屏广播发送完成后才调用的
private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//开始发送广播之前会打印类似“power_screen_broadcast_send: 1”的日志
//这里会在event log中打印类似“power_screen_broadcast_done: [1,125,1]“的日志
//里面包含了发送亮屏广播的时间,此处是“125 ms”
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
sendNextBroadcast();
}
};
private void sendWakeUpBroadcast() {
if (DEBUG) {
Slog.d(TAG, "Sending wake up broadcast.");
}
if (mActivityManagerInternal.isSystemReady()) {
//调用的是ContextImpl的sendOrderedBroadcastAsUser去发送广播
//mScreenOnIntent是发送的亮屏广播
//mHandler是PowerManagerService.java的主线程,用来运行mWakeUpBroadcastDone
//mWakeUpBroadcastDone是亮屏广播发送完成后
mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
mWakeUpBroadcastDone, mHandler, 0, null, null);
} else {
EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
sendNextBroadcast();
}
}
//ContextImpl.java
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
int initialCode, String initialData, Bundle initialExtras) {
//多带了appOp=OP_NONE、options=null的参数
sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
}
public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
IIntentReceiver rd = null;
if (resultReceiver != null) {
if (mPackageInfo != null) {
if (scheduler == null) {
//由于传入了scheduler(mHandler),所以这里是不会进来的
scheduler = mMainThread.getHandler();
}
//进入的是这里获取IIntentReceiver rd(通过mPackageInfo、resultReceiver、scheduler构建)
rd = mPackageInfo.getReceiverDispatcher(
resultReceiver, getOuterContext(), scheduler,
mMainThread.getInstrumentation(), false);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
scheduler, null, false).getIIntentReceiver();
}
}
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
String[] receiverPermissions = receiverPermission == null ? null
: new String[] {receiverPermission};
try {
intent.prepareToLeaveProcess(this);
//实际是调用的AMS的broadcastIntentWithFeature方法
ActivityManager.getService().broadcastIntentWithFeature(
mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
rd, initialCode, initialData, initialExtras, receiverPermissions,
null /*excludedPermissions=*/, appOp, options, true, false,
user.getIdentifier());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
系统AMS通过broadcastIntentWithFeature接收广播的请求
//ActivityManagerService.java
//从context过来的都走的这个broadcastIntentWithFeature方法,带特性的发送广播
public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, String[] excludedPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
//通过IApplicationThread获取调用者ProcessRecord callerApp
final ProcessRecord callerApp = getRecordForAppLOSP(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
//获取callerApp、callingPid、callingUid用于广播发送参数传入
return broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, excludedPermissions, appOp, bOptions, serialized,
sticky, callingPid, callingUid, callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, String callerFeatureId, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions,
int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid,
int callingUid, int realCallingUid, int realCallingPid, int userId) {
//这里再次增加了3个参数allowBackgroundActivityStarts=false,tokenNeededForBackgroundActivityStarts=false
//broadcastAllowList=null
return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent,
resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions,
excludedPermissions, appOp, bOptions, ordered, sticky, callingPid, callingUid,
realCallingUid, realCallingPid, userId, false /* allowBackgroundActivityStarts */,
null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */);
}
@GuardedBy("this")
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage,
@Nullable String callerFeatureId, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions,
String[] excludedPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid,
int realCallingUid, int realCallingPid, int userId,
boolean allowBackgroundActivityStarts,
@Nullable IBinder backgroundActivityStartsToken,
@Nullable int[] broadcastAllowList) {
intent = new Intent(intent);
//调用者是否即时app
final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
// Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
//如果调用者是即时app,不能添加FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,可以让即时app接收的flag
if (callerInstantApp) {
intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
}
// broadcastAllowList: 允许接收该广播uid的列表;一般包信息改变的时候才会传入,通过ContextImpl发送广播是不带这个参数的
// broadcastAllowList目前只在PMS的doSendBroadcast发送package相关广播的时候才可能使用到
// PackageManagerService.sendPackageBroadcast/sendMyPackageSuspendedOrUnsuspended->doSendBroadcast->
// ActivityManagerService.LocalService.broadcastIntent
if (userId == UserHandle.USER_ALL && broadcastAllowList != null) {
Slog.e(TAG, "broadcastAllowList only applies when sending to individual users. "
+ "Assuming restrictive whitelist.");
broadcastAllowList = new int[]{};
}
// By default broadcasts do not go to stopped apps.
//默认广播是不发送给stop的应用的,类似于安装后进程从未启动过,或者给强行停止的应用,
//是无法通过接收静态注册的广播来启动的(具体在IntentResolver.java的buildResolveList会使用)
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
// If we have not finished booting, don't allow this to launch new processes.
//mProcessesReady在systemReady的时候会设置为true
//在系统没有启动完成的时候,而且广播发送没有带FLAG_RECEIVER_BOOT_UPGRADE的flag
if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
//则默认只能发送到动态注册的接收者中,静态注册的全部无法接收
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
//DEBUG_BROADCAST_LIGHT这个是调试日志的开关,这里输出是否order有序广播
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
(sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
+ " ordered=" + ordered + " userid=" + userId);
//如果是非ordered的广播,而且有resultTo则输出warning的信息
//一般情况下orderd的广播才会设置resultTo(发送完成后返回完成的结果到发送者)
if ((resultTo != null) && !ordered) {
Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
}
//多用户判断,如果是callingUid、userId同一个用户组,则直接返回userId
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
ALLOW_NON_FULL, "broadcast", callerPackage);
// Make sure that the user who is receiving this broadcast or its parent is running.
// If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
//如果userId不是发送到所有用户USER_ALL(-1),而且当前userId和它的父亲userId都没有在运行
if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
//如果调用者不是系统或者没有设置FLAG_RECEIVER_BOOT_UPGRADE,而且不是关机广播,
//则跳过本次广播发送,不允许stop的userId发送广播,原因是user已经stop了
if ((callingUid != SYSTEM_UID
|| (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
&& !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
Slog.w(TAG, "Skipping broadcast of " + intent
+ ": user " + userId + " and its parent (if any) are stopped");
return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
}
}
//获取其意图的action
final String action = intent.getAction();
BroadcastOptions brOptions = null;
//是否有传入BroadcastOptions的Bundle,开机广播有传入bOptions,亮屏幕广播没有bOptions
if (bOptions != null) {
//将Bundle转换成BroadcastOptions brOptions
brOptions = new BroadcastOptions(bOptions);
//如果mTemporaryAppAllowlistDuration的值大于0
if (brOptions.getTemporaryAppAllowlistDuration() > 0) {
// See if the caller is allowed to do this. Note we are checking against
// the actual real caller (not whoever provided the operation as say a
// PendingIntent), because that who is actually supplied the arguments.
// 检查一下realCallingPid/realCallingUid是否拥有CHANGE_DEVICE_IDLE_TEMP_WHITELIST(修改临时白名单)、
// START_ACTIVITIES_FROM_BACKGROUND(后台启动activity)、
// START_FOREGROUND_SERVICES_FROM_BACKGROUND(后台启动前台服务)的权限,
// 如果一个都没有,则不允许发送该广播,并抛出安全异常
// (在部分情况下callingPid/callingUid调用该发送广播的调用者,
// 于realCallingPid/realCallingUid真实调用者不是一样的)
if (checkComponentPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED
&& checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED
&& checkComponentPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: " + intent.getAction()
+ " broadcast from " + callerPackage + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
+ " requires "
+ CHANGE_DEVICE_IDLE_TEMP_WHITELIST + " or "
+ START_ACTIVITIES_FROM_BACKGROUND + " or "
+ START_FOREGROUND_SERVICES_FROM_BACKGROUND;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
}
//如果带有mDontSendToRestrictedApps不发送给受限制的app
// callingUid不在mActiveUids中,而且callingUid/callerPackage后台限制操作
// 则由于“background restrictions”不允许发送广播
if (brOptions.isDontSendToRestrictedApps()
&& !isUidActiveLOSP(callingUid)
&& isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
+ " has background restrictions");
return ActivityManager.START_CANCELED;
}
//是否允许mAllowBackgroundActivityStarts后台启动activity
if (brOptions.allowsBackgroundActivityStarts()) {
// See if the caller is allowed to do this. Note we are checking against
// the actual real caller (not whoever provided the operation as say a
// PendingIntent), because that who is actually supplied the arguments.
//如果没有START_ACTIVITIES_FROM_BACKGROUND则抛出权限异常
if (checkComponentPermission(
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
realCallingPid, realCallingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: " + intent.getAction()
+ " broadcast from " + callerPackage + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
+ " requires "
+ android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
Slog.w(TAG, msg);
throw new SecurityException(msg);
} else {
//否者将allowBackgroundActivityStarts设置成true,允许后台启动activity
allowBackgroundActivityStarts = true;
// We set the token to null since if it wasn't for it we'd allow anyway here
backgroundActivityStartsToken = null;
}
}
}
// Verify that protected broadcasts are only being sent by system code,
// and that system code is only sending protected broadcasts.
//保护广播的判断逻辑isProtectedBroadcast,这类广播只有系统才能发送
final boolean isProtectedBroadcast;
try {
//查询该广播是否包含在mProtectedBroadcasts,在isProtectedBroadcast也可以增加字符串过滤条件
//例如在frameworks/base/core/res/AndroidManifest.xml等定义的带有“protected-broadcast”的广播
//
isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
} catch (RemoteException e) {
Slog.w(TAG, "Remote exception", e);
return ActivityManager.BROADCAST_SUCCESS;
}
final boolean isCallerSystem;
//判断是否系统调用
switch (UserHandle.getAppId(callingUid)) {
case ROOT_UID:
case SYSTEM_UID:
case PHONE_UID:
case BLUETOOTH_UID:
case NFC_UID:
case SE_UID:
case NETWORK_STACK_UID:
//root用户、系统、phone、蓝牙、nfc、安全、网络等相关调用则被认为是系统
isCallerSystem = true;
break;
default:
//其它就看是否常驻内存,如果是常驻内存调用,也被认为是系统
isCallerSystem = (callerApp != null) && callerApp.isPersistent();
break;
}
// First line security check before anything else: stop non-system apps from
// sending protected broadcasts.
//如果不是系统调用,会进行安全检查
if (!isCallerSystem) {
//如果是保护的广播,则不是系统进程,不允许发送,抛出权限异常
if (isProtectedBroadcast) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from pid="
+ callingPid + ", uid=" + callingUid;
Slog.w(TAG, msg);
throw new SecurityException(msg);
} else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
|| AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
// Special case for compatibility: we don't want apps to send this,
// but historically it has not been protected and apps may be using it
// to poke their own app widget. So, instead of making it protected,
// just limit it to the caller.
//如果是widget配置(ACTION_APPWIDGET_CONFIGURE)和更新(ACTION_APPWIDGET_UPDATE)
//则调用callerPackage不能是空
if (callerPackage == null) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from unknown caller.";
Slog.w(TAG, msg);
throw new SecurityException(msg);
//如果调用组件不等于null
} else if (intent.getComponent() != null) {
// They are good enough to send to an explicit component... verify
// it is being sent to the calling app.
//这种情况只能自己发送给自己,不然抛出权限异常
if (!intent.getComponent().getPackageName().equals(
callerPackage)) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " to "
+ intent.getComponent().getPackageName() + " from "
+ callerPackage;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
} else {
// Limit broadcast to their own package.
//这类广播只能发给它自己,用于自身widget的更新
intent.setPackage(callerPackage);
}
}
}
//这个是广播超时豁免只有ACTION_PRE_BOOT_COMPLETED才会设置
//设置了之后这个广播不会超时,谨慎使用
boolean timeoutExempt = false;
if (action != null) {
//查看是否background的进程也可以接收该广播,具体列表在SystemConfig.java的mAllowImplicitBroadcasts
//这个列表是扫描**/etc(如system/etc/sysconfig/framework-sysconfig.xml、
// /product/etc/sysconfig/google.xml)带有“
// 如:google的云推送”com.google.android.c2dm.intent.RECEIVE“、simcard状态改变
// android.intent.action.SIM_STATE_CHANGED就是这类广播
if (getBackgroundLaunchBroadcasts().contains(action)) {
if (DEBUG_BACKGROUND_CHECK) {
Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
}
//直接增加可以被后台进程接收的flag FLAG_RECEIVER_INCLUDE_BACKGROUND
// (如何使用在讲解BroadcastQueue的processNextBroadcastLocked时会说明)
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
}
switch (action) {
case Intent.ACTION_UID_REMOVED:
case Intent.ACTION_PACKAGE_REMOVED:
case Intent.ACTION_PACKAGE_CHANGED:
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
case Intent.ACTION_PACKAGES_SUSPENDED:
case Intent.ACTION_PACKAGES_UNSUSPENDED:
// Handle special intents: if this broadcast is from the package
// manager about a package being removed, we need to remove all of
// its activities from the history stack.
// 如果是ACTION_UID_REMOVED/ACTION_PACKAGE_REMOVED/ACTION_PACKAGE_CHANGED/
// ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE/ACTION_EXTERNAL_APPLICATIONS_AVAILABLE/
// ACTION_PACKAGES_SUSPENDED/ACTION_PACKAGES_UNSUSPENDED这类广播,
// 则发送广播需要BROADCAST_PACKAGE_REMOVED的权限,不然是没法发送的
if (checkComponentPermission(
android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
callingPid, callingUid, -1, true)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: " + intent.getAction()
+ " broadcast from " + callerPackage + " (pid=" + callingPid
+ ", uid=" + callingUid + ")"
+ " requires "
+ android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
switch (action) {
case Intent.ACTION_UID_REMOVED:
final int uid = getUidFromIntent(intent);
//如果发送的是ACTION_UID_REMOVED的广播
if (uid >= 0) {
//电池状态服务的removeUid
mBatteryStatsService.removeUid(uid);
//mAppOpsService app操作相关管理的处理
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
mAppOpsService.resetAllModes(UserHandle.getUserId(uid),
intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME));
} else {
mAppOpsService.uidRemoved(uid);
}
}
break;
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
// If resources are unavailable just force stop all those packages
// and flush the attribute cache as well.
String list[] =
intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
if (list != null && list.length > 0) {
for (int i = 0; i < list.length; i++) {
forceStopPackageLocked(list[i], -1, false, true, true,
false, false, userId, "storage unmount");
}
mAtmInternal.cleanupRecentTasksForUser(UserHandle.USER_ALL);
sendPackageBroadcastLocked(
ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
list, userId);
}
break;
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
mAtmInternal.cleanupRecentTasksForUser(UserHandle.USER_ALL);
break;
case Intent.ACTION_PACKAGE_REMOVED:
case Intent.ACTION_PACKAGE_CHANGED:
//应用移除或者改变
Uri data = intent.getData();
String ssp;
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
final boolean replacing =
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
final boolean killProcess =
!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
final boolean fullUninstall = removed && !replacing;
if (removed) {
if (killProcess) {
forceStopPackageLocked(ssp, UserHandle.getAppId(
intent.getIntExtra(Intent.EXTRA_UID, -1)),
false, true, true, false, fullUninstall, userId,
removed ? "pkg removed" : "pkg changed");
} else {
// Kill any app zygotes always, since they can't fork new
// processes with references to the old code
forceStopAppZygoteLocked(ssp, UserHandle.getAppId(
intent.getIntExtra(Intent.EXTRA_UID, -1)),
userId);
}
final int cmd = killProcess
? ApplicationThreadConstants.PACKAGE_REMOVED
: ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
sendPackageBroadcastLocked(cmd,
new String[] {ssp}, userId);
if (fullUninstall) {
mAppOpsService.packageRemoved(
intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
// Remove all permissions granted from/to this package
mUgmInternal.removeUriPermissionsForPackage(ssp, userId,
true, false);
mAtmInternal.removeRecentTasksByPackageName(ssp, userId);
mServices.forceStopPackageLocked(ssp, userId);
mAtmInternal.onPackageUninstalled(ssp);
mBatteryStatsService.notePackageUninstalled(ssp);
}
} else {
if (killProcess) {
final int extraUid = intent.getIntExtra(Intent.EXTRA_UID,
-1);
synchronized (mProcLock) {
mProcessList.killPackageProcessesLSP(ssp,
UserHandle.getAppId(extraUid),
userId, ProcessList.INVALID_ADJ,
ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
"change " + ssp);
}
}
cleanupDisabledPackageComponentsLocked(ssp, userId,
intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
mServices.schedulePendingServiceStartLocked(ssp, userId);
} }
break;
case Intent.ACTION_PACKAGES_SUSPENDED:
case Intent.ACTION_PACKAGES_UNSUSPENDED:
final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
intent.getAction());
final String[] packageNames = intent.getStringArrayExtra(
Intent.EXTRA_CHANGED_PACKAGE_LIST);
final int userIdExtra = intent.getIntExtra(
Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mAtmInternal.onPackagesSuspendedChanged(packageNames, suspended,
userIdExtra);
break;
}
break;
case Intent.ACTION_PACKAGE_REPLACED:
{
final Uri data = intent.getData();
final String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
ApplicationInfo aInfo = null;
try {
aInfo = AppGlobals.getPackageManager()
.getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
} catch (RemoteException ignore) {}
if (aInfo == null) {
Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
+ " ssp=" + ssp + " data=" + data);
return ActivityManager.BROADCAST_SUCCESS;
}
updateAssociationForApp(aInfo);
mAtmInternal.onPackageReplaced(aInfo);
mServices.updateServiceApplicationInfoLocked(aInfo);
sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
new String[] {ssp}, userId);
}
break;
}
case Intent.ACTION_PACKAGE_ADDED:
{
//应用安装
// Special case for adding a package: by default turn on compatibility mode.
Uri data = intent.getData();
String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
final boolean replacing =
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
mAtmInternal.onPackageAdded(ssp, replacing);
try {
ApplicationInfo ai = AppGlobals.getPackageManager().
getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
mBatteryStatsService.notePackageInstalled(ssp,
ai != null ? ai.longVersionCode : 0);
} catch (RemoteException e) {
}
}
break;
}
case Intent.ACTION_PACKAGE_DATA_CLEARED:
{
//应用数据清除
Uri data = intent.getData();
String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
mAtmInternal.onPackageDataCleared(ssp);
}
break;
}
case Intent.ACTION_TIMEZONE_CHANGED:
// If this is the time zone changed action, queue up a message that will reset
// the timezone of all currently running processes. This message will get
// queued up before the broadcast happens.
//时区改变
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
break;
case Intent.ACTION_TIME_CHANGED:
// EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
// the tri-state value it may contain and "unknown".
// For convenience we re-use the Intent extra values.
//系统时间改变
final int NO_EXTRA_VALUE_FOUND = -1;
final int timeFormatPreferenceMsgValue = intent.getIntExtra(
Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
NO_EXTRA_VALUE_FOUND /* defaultValue */);
// Only send a message if the time preference is available.
if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
Message updateTimePreferenceMsg =
mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
timeFormatPreferenceMsgValue, 0);
mHandler.sendMessage(updateTimePreferenceMsg);
}
mBatteryStatsService.noteCurrentTimeChanged();
break;
case ConnectivityManager.ACTION_CLEAR_DNS_CACHE:
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
break;
case Proxy.PROXY_CHANGE_ACTION:
mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG));
break;
case android.hardware.Camera.ACTION_NEW_PICTURE:
case android.hardware.Camera.ACTION_NEW_VIDEO:
// In N we just turned these off; in O we are turing them back on partly,
// only for registered receivers. This will still address the main problem
// (a spam of apps waking up when a picture is taken putting significant
// memory pressure on the system at a bad point), while still allowing apps
// that are already actively running to know about this happening.
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
break;
case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
break;
case "com.android.launcher.action.INSTALL_SHORTCUT":
// As of O, we no longer support this broadcasts, even for pre-O apps.
// Apps should now be using ShortcutManager.pinRequestShortcut().
Log.w(TAG, "Broadcast " + action
+ " no longer supported. It will not be delivered.");
return ActivityManager.BROADCAST_SUCCESS;
case Intent.ACTION_PRE_BOOT_COMPLETED:
//如果是ACTION_PRE_BOOT_COMPLETED广播则设置超时豁免timeoutExempt = true
timeoutExempt = true;
break;
case Intent.ACTION_CLOSE_SYSTEM_DIALOGS:
//需要有BROADCAST_CLOSE_SYSTEM_DIALOGS的权限,不然直接返回
if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid,
callerPackage)) {
// Returning success seems to be the pattern here
return ActivityManager.BROADCAST_SUCCESS;
}
break;
}
if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
final int uid = getUidFromIntent(intent);
if (uid != -1) {
final UidRecord uidRec = mProcessList.getUidRecordLOSP(uid);
if (uidRec != null) {
uidRec.updateHasInternetPermission();
}
}
}
}
将粘性广播添加到AMS的mStickyBroadcasts(key是用户组,value是粘性广播列表stickies)中,
单个用户组的粘性广播列表stickies(key是action,value是intent)
已经发送的粘性广播会放入AMS的mStickyBroadcasts中,后面动态注册的接收者就可以在注册的时候就接收这类粘性广播, 因为系统有保存这类广播
// Add to the sticky list if requested.
// 是否粘性广播,可以通过ContextImpl.java的sendStickyBroadcast/sendStickyBroadcastAsUser/
// sendStickyOrderedBroadcast/sendStickyOrderedBroadcastAsUser来进行发送
if (sticky) {
//粘性广播需要拥有"android.permission.BROADCAST_STICKY"的权限
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
callingPid, callingUid)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
+ callingPid + ", uid=" + callingUid
+ " requires " + android.Manifest.permission.BROADCAST_STICKY;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
//这类广播不能带有requiredPermissions,否则直接返回
if (requiredPermissions != null && requiredPermissions.length > 0) {
Slog.w(TAG, "Can't broadcast sticky intent " + intent
+ " and enforce permissions " + Arrays.toString(requiredPermissions));
return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
}
//粘性广播不能指定发送到相关组件,否则发出安全异常
if (intent.getComponent() != null) {
throw new SecurityException(
"Sticky broadcasts can't target a specific component");
}
// We use userId directly here, since the "all" target is maintained
// as a separate set of sticky broadcasts.
//如果userId不是发送给所有用户USER_ALL(-1)
if (userId != UserHandle.USER_ALL) {
// But first, if this is not a broadcast to all users, then
// make sure it doesn't conflict with an existing broadcast to
// all users.
//则取出保存粘性广播的列表mStickyBroadcasts里面相同action的Intent
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
UserHandle.USER_ALL);
if (stickies != null) {
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list != null) {
int N = list.size();
int i;
for (i=0; i<N; i++) {
//粘性广播2个Intent不能完全相同,相同的话会抛出非法参数异常
//mAction/mData/mType/mIdentifier/mPackage/mComponent/mCategories都一致filterEquals才会返回true
if (intent.filterEquals(list.get(i))) {
throw new IllegalArgumentException(
"Sticky broadcast " + intent + " for user "
+ userId + " conflicts with existing global broadcast");
}
}
}
}
}
//获取该用户组的粘性广播列表stickies
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
if (stickies == null) {
//如果stickies是null,则新建一个
stickies = new ArrayMap<>();
//并添加到mStickyBroadcasts中key为userId中去
mStickyBroadcasts.put(userId, stickies);
}
//通过粘性广播列表stickies(key是action,value是intent)
ArrayList<Intent> list = stickies.get(intent.getAction());
if (list == null) {
//如果list为空,则新建一个ArrayList,并放入stickies
list = new ArrayList<>();
stickies.put(intent.getAction(), list);
}
final int stickiesCount = list.size();
int i;
for (i = 0; i < stickiesCount; i++) {
//mAction/mData/mType/mIdentifier/mPackage/mComponent/mCategories都一致filterEquals才会返回true
if (intent.filterEquals(list.get(i))) {
// This sticky already exists, replace it.
//如果之前存在一样的intent,则直接替换掉旧的,并且退出循环
list.set(i, new Intent(intent));
break;
}
}
//如果上面中途替换过list的intent,则i < stickiesCount
//而i >= stickiesCount则代表没有替换过
if (i >= stickiesCount) {
//没有替换过则加入list中去
list.add(new Intent(intent));
}
}
int[] users;
//通过userId,获取多用户的users
if (userId == UserHandle.USER_ALL) {
// Caller wants broadcast to go to all started users.
users = mUserController.getStartedUserArray();
} else {
// Caller wants broadcast to go to one specific user.
users = new int[] {userId};
}
// Figure out who all will receive this broadcast.
// 静态广播接受者或者order的动态广播接受者的列表
List receivers = null;
// 动态广播接受者列表
List<BroadcastFilter> registeredReceivers = null;
// Need to resolve the intent to interested receivers...
//静态广播的接收,只要没有设置FLAG_RECEIVER_REGISTERED_ONLY,都会查询发送到静态广播中,
//不过如常见的Intent.ACTION_SCREEN_ON则发送时则有设置这个flag,于是Intent.ACTION_SCREEN_ON不会发送给静态广播
//不要注册Intent.ACTION_SCREEN_ON的静态广播,这个注册了你也收不到
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
== 0) {
//这里就是查询静态广播的地方,通过PMS的mComponentResolver查询得到该intent静态注册的广播接受者
//同时传入broadcastAllowList过滤是否允许接受者接收
receivers = collectReceiverComponents(
intent, resolvedType, callingUid, users, broadcastAllowList);
}
collectReceiverComponents:收集静态接收者的函数,其调用的是PMS的queryIntentReceivers进行查询,然后进行相应过滤。
=> 调用的是PMS的queryIntentReceivers进行查询
=> 判断是否只发送到单个用户FLAG_SYSTEM_USER_ONLY(多用户场景使用),如果是则进行过滤,只发送给单个用户
=> 如果带有broadcastAllowList(允许接收该广播uid的列表),则只让特定uid列表的静态接收者接收
private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
int callingUid, int[] users, int[] broadcastAllowList) {
// TODO: come back and remove this assumption to triage all broadcasts
int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
List<ResolveInfo> receivers = null;
try {
HashSet<ComponentName> singleUserReceivers = null;
boolean scannedFirstReceivers = false;
for (int user : users) {
// Skip users that have Shell restrictions
//如果调用者是shell,而且该user不允许shell调试,则跳过
if (callingUid == SHELL_UID
&& mUserController.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
continue;
}
//静态广播通过PMS去查询接收者
List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
.queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
// If this is not the system user, we need to check for
// any receivers that should be filtered out.
for (int i=0; i<newReceivers.size(); i++) {
ResolveInfo ri = newReceivers.get(i);
//如果取出来的ResolveInfo包含了只允许系统接收的flag(FLAG_SYSTEM_USER_ONLY),
//则从筛选出来的列表中移除这个接收者
if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
newReceivers.remove(i);
i--;
}
}
}
//如果到目前为止newReceivers(ResolveInfo列表)为null或者空的
if (newReceivers != null && newReceivers.size() == 0) {
newReceivers = null;
}
if (receivers == null) {
//如果receivers(最后返回的结果)为null,则先将newReceivers赋值给receivers
receivers = newReceivers;
} else if (newReceivers != null) {
// We need to concatenate the additional receivers
// found with what we have do far. This would be easy,
// but we also need to de-dup any receivers that are
// singleUser.
//scannedFirstReceivers默认是fasle,也就是第一次跑到这段代码会进来,只进来一次
//receivers此时已经赋值过一次,这里是users第二次和以上循环才可能会进来
if (!scannedFirstReceivers) {
// Collect any single user receivers we had already retrieved.
scannedFirstReceivers = true;
// 遍历之前的receivers(这里receivers没有判空逻辑,只看这段逻辑不太严谨,
// 没有出错是由于newReceivers有判空)
for (int i=0; i<receivers.size(); i++) {
ResolveInfo ri = receivers.get(i);
//如果接收者包含FLAG_SINGLE_USER的flag
if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
ComponentName cn = new ComponentName(
ri.activityInfo.packageName, ri.activityInfo.name);
if (singleUserReceivers == null) {
singleUserReceivers = new HashSet<ComponentName>();
}
//则把这类组件add到singleUserReceivers中
singleUserReceivers.add(cn);
}
}
}
// Add the new results to the existing results, tracking
// and de-dupping single user receivers.
// 遍历新的users中获取的newReceivers
for (int i=0; i<newReceivers.size(); i++) {
ResolveInfo ri = newReceivers.get(i);
//如果也是带有FLAG_SINGLE_USER的flag,只发送给单个user
if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
ComponentName cn = new ComponentName(
ri.activityInfo.packageName, ri.activityInfo.name);
if (singleUserReceivers == null) {
singleUserReceivers = new HashSet<ComponentName>();
}
//如果之前还没有添加过,才进行receivers添加
if (!singleUserReceivers.contains(cn)) {
//而且将单个用户接受者ComponentName cn添加到ComponentName中
singleUserReceivers.add(cn);
receivers.add(ri);
}
} else {
//其它情况则直接加入该接收者到receivers
receivers.add(ri);
}
}
}
}
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
//如果带有broadcastAllowList,允许接收该广播uid的列表
if (receivers != null && broadcastAllowList != null) {
for (int i = receivers.size() - 1; i >= 0; i--) {
final int receiverAppId = UserHandle.getAppId(
receivers.get(i).activityInfo.applicationInfo.uid);
//接受者的uid如果是app进程,而且不在允许接收该广播uid的列表,则移除查询到的接收者
if (receiverAppId >= Process.FIRST_APPLICATION_UID
&& Arrays.binarySearch(broadcastAllowList, receiverAppId) < 0) {
receivers.remove(i);
}
}
}
//返回接受者
return receivers;
}
=> 如果包发送给特定组件,则通过mComponentResolver的mReceivers.mActivities获取ParsedActivity,并最终得到对应的ActivityInfo
=> 如果没有指定特定组件和特定包,则通过mComponentResolver查询recevier,
调用的是IntentResolver的queryIntent,根据各类Filter去查询,如mActionToFilter,
查询到结果后在通过buildResolveList构建返回的结果List result
=> 如果是发送给特定包,则通过mPackages(安装的时候保存的,key是包名,
value是AndroidPackage/ParsingPackageImpl/PackageImpl)获取AndroidPackage(ParsingPackageImpl),
通过ParsingPackageImpl得到这个包的receivers(pkg.getReceivers()),
然后通过mComponentResolver的queryReceivers(ComponentResolver.java)->mReceivers.queryIntentForPackage
queryIntentFromList(IntentResolver.java)->buildResolveList
此处queryIntentFromList只查询这个包的receivers(构建Pair
在这里可以看到之前“Android S静态广播注册流程”中提到的用来保存静态注册广播组件的mComponentResolver、mReceivers.mActivities、receivers
//PackageManagerService.java
public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
String resolvedType, int flags, int userId) {
//内部方法查询该intent的接受者queryIntentReceiversInternal
return new ParceledListSlice<>(
queryIntentReceiversInternal(intent, resolvedType, flags, userId,
false /*allowDynamicSplits*/));
}
private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
//userId不存在则返回空
if (!mUserManager.exists(userId)) return Collections.emptyList();
final int callingUid = Binder.getCallingUid();
//callingUid是否拥有INTERACT_ACROSS_USERS_FULL或者INTERACT_ACROSS_USERS的权限
enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
false /*checkShell*/, "query intent receivers");
//看一下callingUid是否即时app,如果是则返回包名,如果不是则返回null
final String instantAppPkgName = getInstantAppPackageName(callingUid);
//更新一下flags
flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
flags));
//获取intent意图的ComponentName
ComponentName comp = intent.getComponent();
if (comp == null) {
//如果为空,再从intent的selector中查询组件
if (intent.getSelector() != null) {
intent = intent.getSelector();
comp = intent.getComponent();
}
}
if (comp != null) {
//如果ComponentName组件不为null,则代表发送给特定的组件
final List<ResolveInfo> list = new ArrayList<>(1);
//通过组件获取ActivityInfo
final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
if (ai != null) {
// When specifying an explicit component, we prevent the activity from being
// used when either 1) the calling package is normal and the activity is within
// an instant application or 2) the calling package is ephemeral and the
// activity is not visible to instant applications.
final boolean matchInstantApp =
(flags & PackageManager.MATCH_INSTANT) != 0;
final boolean matchVisibleToInstantAppOnly =
(flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
final boolean matchExplicitlyVisibleOnly =
(flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
final boolean isCallerInstantApp =
instantAppPkgName != null;
final boolean isTargetSameInstantApp =
comp.getPackageName().equals(instantAppPkgName);
final boolean isTargetInstantApp =
(ai.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
final boolean isTargetVisibleToInstantApp =
(ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
final boolean isTargetExplicitlyVisibleToInstantApp =
isTargetVisibleToInstantApp
&& (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
final boolean isTargetHiddenFromInstantApp =
!isTargetVisibleToInstantApp
|| (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
final boolean blockResolution =
!isTargetSameInstantApp
&& ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
|| (matchVisibleToInstantAppOnly && isCallerInstantApp
&& isTargetHiddenFromInstantApp));
//如果blockResolution为fasle(一般情况除了InstantApp,其它为fasle)
if (!blockResolution) {
ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
//添加到List list中
list.add(ri);
}
}
//将查询到的List list再次做一些判断,看是否需要移除
return applyPostResolutionFilter(
list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
}
// reader
synchronized (mLock) {
//看一下是否有发送给特定的包
String pkgName = intent.getPackage();
if (pkgName == null) {
//如果pkgName为空,则通过mComponentResolver查询recevier
//调用的是IntentResolver的queryIntent,根据各类Filter去查询,如mActionToFilter
//查询到结果后在通过buildResolveList构建返回的结果List result
final List<ResolveInfo> result =
mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
if (result == null) {
return Collections.emptyList();
}
//过滤后返回结果
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
}
//如果有发送给特定的包
final AndroidPackage pkg = mPackages.get(pkgName);
if (pkg != null) {
// 则queryReceivers(ComponentResolver.java)->mReceivers.queryIntentForPackage
// queryIntentFromList(IntentResolver.java)->buildResolveList
// 只查询这个包的receivers(构建Pair来查询)
final List<ResolveInfo> result = mComponentResolver.queryReceivers(
intent, resolvedType, flags, pkg.getReceivers(), userId);
if (result == null) {
return Collections.emptyList();
}
//过滤后返回结果
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
}
return Collections.emptyList();
}
}
//查询单个组件的ActivityInfo:通过组件名,可以获得相应的ParsedActivity,最终返回的是ActivityInfo信息
public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
if (!mUserManager.exists(userId)) return null;
final int callingUid = Binder.getCallingUid();
flags = updateFlagsForComponent(flags, userId);
enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
false /* checkShell */, "get receiver info");
synchronized (mLock) {
//通过mComponentResolver(mReceivers.mActivities取)查询该组件的ParsedActivity
ParsedActivity a = mComponentResolver.getReceiver(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
if (a == null) {
//如果没有取出来,则返回null
return null;
}
//mPackages变量是保存了所有安装的应用,查看一下这个package是否能从安装应用中查出来
AndroidPackage pkg = mPackages.get(a.getPackageName());
if (pkg == null) {
return null;
}
// 是否包enable(这个是ParsingPackageImpl的ENABLED,不是PackageSettingBase的enabledComponents/disabledComponents)
// 和匹配
if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
//从mSettings中获取包信息PackageSetting ps
PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
if (ps == null) return null;
//查看一下是否需要根据callingUid过滤是否可见其它目标的package
//系统调用的话返回false
if (shouldFilterApplicationLocked(
ps, callingUid, component, TYPE_RECEIVER, userId)) {
return null;
}
//根据pkg和ParsedActivity生成相应的ActivityInfo信息
return PackageInfoUtils.generateActivityInfo(pkg,
a, flags, ps.readUserState(userId), userId, ps);
}
}
return null;
}
“Android S动态广播注册流程”中有讲到:动态广播注册其实最终构建的是BroadcastFilter bf,并放入mReceiverResolver中去
而放入mReceiverResolver使用的方法是IntentResolver的addFilter在“Android S静态广播注册流程”也有提到。
if (intent.getComponent() == null) {
//如果intent不是单独发给某个组件的话
//如果userId == UserHandle.USER_ALL(发给所有用户)而且callingUid == SHELL_UID(从shell过来)
//一般app或者系统发送不是用过这个场景来发送的
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
// Query one target user at a time, excluding shell-restricted users
for (int i = 0; i < users.length; i++) {
if (mUserController.hasUserRestriction(
UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
continue;
}
//通过动态注册广播的解析器mReceiverResolver,查询动态注册的接受者
//也是通过IntentResolver.java的queryIntent来查询的
List<BroadcastFilter> registeredReceiversForUser =
mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, users[i]);
//将查询到的接受者添加到registeredReceivers中去
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
} else if (registeredReceiversForUser != null) {
registeredReceivers.addAll(registeredReceiversForUser);
}
}
} else {
//一般情况我们走的这里,直接从mReceiverResolver查询动态接受者赋值给registeredReceivers
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, userId);
}
}
=> 通过***Filter(如mActionToFilter)找出匹配的fliter
=> 通过buildResolveList构建可以被接收的结果
=> 通过优先级排序返回查询结果
//IntentResolver.java
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
int userId) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
final boolean debug = localLOGV ||
((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
if (debug) Slog.v(
TAG, "Resolving type=" + resolvedType + " scheme=" + scheme
+ " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent);
F[] firstTypeCut = null;
F[] secondTypeCut = null;
F[] thirdTypeCut = null;
F[] schemeCut = null;
// If the intent includes a MIME type, then we want to collect all of
// the filters that match that MIME type.
if (resolvedType != null) {
int slashpos = resolvedType.indexOf('/');
if (slashpos > 0) {
final String baseType = resolvedType.substring(0, slashpos);
if (!baseType.equals("*")) {
if (resolvedType.length() != slashpos+2
|| resolvedType.charAt(slashpos+1) != '*') {
// Not a wild card, so we can just look for all filters that
// completely match or wildcards whose base type matches.
firstTypeCut = mTypeToFilter.get(resolvedType);
if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
secondTypeCut = mWildTypeToFilter.get(baseType);
if (debug) Slog.v(TAG, "Second type cut: "
+ Arrays.toString(secondTypeCut));
} else {
// We can match anything with our base type.
firstTypeCut = mBaseTypeToFilter.get(baseType);
if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
secondTypeCut = mWildTypeToFilter.get(baseType);
if (debug) Slog.v(TAG, "Second type cut: "
+ Arrays.toString(secondTypeCut));
}
// Any */* types always apply, but we only need to do this
// if the intent type was not already */*.
thirdTypeCut = mWildTypeToFilter.get("*");
if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
} else if (intent.getAction() != null) {
// The intent specified any type ({@literal *}/*). This
// can be a whole heck of a lot of things, so as a first
// cut let's use the action instead.
firstTypeCut = mTypedActionToFilter.get(intent.getAction());
if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
}
}
}
// If the intent includes a data URI, then we want to collect all of
// the filters that match its scheme (we will further refine matches
// on the authority and path by directly matching each resulting filter).
if (scheme != null) {
schemeCut = mSchemeToFilter.get(scheme);
if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
}
// If the intent does not specify any data -- either a MIME type or
// a URI -- then we will only be looking for matches against empty
// data.
if (resolvedType == null && scheme == null && intent.getAction() != null) {
//这里就把所有的ParsedIntentInfo从mActionToFilter取出来了, key是action, value是Pair(ParsedActivity, ParsedIntentInfo)
//如我们之前动态注册的亮屏广播mDynamicReceiver,静态注册的开机广播MyReceiver
/*
//动态注册的亮屏广播mReceiverResolver.queryIntent时
firstTypeCut = {BroadcastFilter[42]@39131}
40 = {BroadcastFilter@39150} "BroadcastFilter{8f17ce8 10214/u0 ReceiverList{50ee60b 9948 com.example.myapplication/10214/u0 remote:7781da}}"
//静态注册的开机广播mComponentResolver.mReceivers.queryIntent时
firstTypeCut = {Pair[316]@38034}
107 = {Pair@38369} "Pair{Activity{7d26902 com.example.myapplication/.MyReceiver2} ParsedIntentInfo{a218213}}"
108 = {Pair@38370} "Pair{Activity{3985c50 com.example.myapplication/.MyReceiver} ParsedIntentInfo{9dfde49}}"
*/
firstTypeCut = mActionToFilter.get(intent.getAction());
if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
}
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
if (firstTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, firstTypeCut, finalList, userId);
}
if (secondTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, secondTypeCut, finalList, userId);
}
if (thirdTypeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, thirdTypeCut, finalList, userId);
}
if (schemeCut != null) {
buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
scheme, schemeCut, finalList, userId);
}
//这里对于即时应用才有过滤效果,普通的是直接返回
filterResults(finalList);
//通过getPriority优先级排序
sortResults(finalList);
if (debug) {
Slog.v(TAG, "Final result list:");
for (int i=0; i<finalList.size(); i++) {
Slog.v(TAG, " " + finalList.get(i));
}
}
return finalList;
}
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
boolean debug, boolean defaultOnly, String resolvedType, String scheme,
F[] src, List<R> dest, int userId) {
//获取action
final String action = intent.getAction();
//获取data
final Uri data = intent.getData();
//获取包名
final String packageName = intent.getPackage();
//是否flag包含了FLAG_INCLUDE_STOPPED_PACKAGES(发送给停止的包)
final boolean excludingStopped = intent.isExcludingStopped();
final Printer logPrinter;
final PrintWriter logPrintWriter;
//调试使用的debug开关,localLOGV或者设置了FLAG_DEBUG_LOG_RESOLUTION时debug会是true
if (debug) {
logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
logPrintWriter = new FastPrintWriter(logPrinter);
} else {
logPrinter = null;
logPrintWriter = null;
}
final int N = src != null ? src.length : 0;
boolean hasNonDefaults = false;
int i;
F filter;
//遍历需要筛选的src,动态广播是BroadcastFilter,静态广播是Pair
for (i=0; i<N && (filter=src[i]) != null; i++) {
int match;
if (debug) Slog.v(TAG, "Matching against filter " + filter);
if (excludingStopped) {
//1. 静态广播的mComponentResolver.mReceivers是继承于ActivityIntentResolver的
// 其调用ComponentResolver.isFilterStopped会针对非系统应用判断是否stop停止的应用
// 主要代码是!ps.isSystem() && ps.getStopped(userId);,这里就不扩展讲了
//2. 非静态广播mReceiverResolver是new IntentResolver,直接返回false
if (isFilterStopped(filter, userId)) {
if (debug) {
Slog.v(TAG, " Filter's target is stopped; skipping");
}
continue;
}
}
// Is delivery being limited to filters owned by a particular package?
//这里是当intent发送给特定包的时候,判断是否当前filter
if (packageName != null && !isPackageForFilter(packageName, filter)) {
if (debug) {
Slog.v(TAG, " Filter is not from package " + packageName + "; skipping");
}
continue;
}
// Are we verified ?
//获取filter,动态的是BroadcastFilter,静态的是ParsedIntentInfo
IntentFilter intentFilter = getIntentFilter(filter);
//查看是否带有STATE_VERIFY_AUTO,这里只是打印日志
if (intentFilter.getAutoVerify()) {
if (localVerificationLOGV || debug) {
Slog.v(TAG, " Filter verified: " + isFilterVerified(filter));
int authorities = intentFilter.countDataAuthorities();
for (int z = 0; z < authorities; z++) {
Slog.v(TAG, " " + intentFilter.getDataAuthority(z)
.getHost());
}
}
}
// Do we already have this one?
//如果在dest中添加过一样的,则不在添加,跳过
if (!allowFilterResult(filter, dest)) {
if (debug) {
Slog.v(TAG, " Filter's target already added");
}
continue;
}
//判断过滤器是否匹配
match = intentFilter.match(action, resolvedType, scheme, data, categories, TAG);
if (match >= 0) {
if (debug) Slog.v(TAG, " Filter matched! match=0x" +
Integer.toHexString(match) + " hasDefault="
+ intentFilter.hasCategory(Intent.CATEGORY_DEFAULT));
// 对于接收者receiver来说:
// 动态注册者mReceiverResolver.queryIntent的时候传入的defaultOnly=false
// 静态注册者查询时需要设置了MATCH_DEFAULT_ONLY才会将defaultOnly设置成true,
// 默认AMS收集静态注册者的时候是没有设置这个flag的,于是defaultOnly都是false
if (!defaultOnly || intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) {
final R oneResult = newResult(filter, match, userId);
if (debug) Slog.v(TAG, " Created result: " + oneResult);
if (oneResult != null) {
//将匹配的filter生成的结果放入dest中
dest.add(oneResult);
if (debug) {
dumpFilter(logPrintWriter, " ", filter);
logPrintWriter.flush();
intentFilter.dump(logPrinter, " ");
}
}
} else {
hasNonDefaults = true;
}
}
//...
}
如果没有设置ordered(也称之为serialized)按顺序,则针对动态注册类型的广播会一次性全部发送出去,
于是我们可以看到类似这样的日志:“Enqueueing parallel broadcas ***”,
这种无需等待APP的执行,很快系统就处理完了
//是否拥FLAG_RECEIVER_REPLACE_PENDING,这类广播会将旧的广播给覆盖替换掉
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
//replacePending也在调试开关下输出一下日志
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
+ " replacePending=" + replacePending);
//动态注册查询的时候没有传入broadcastAllowList(允许接收的uid列表)
//此处会根据broadcastAllowList(不为null才会过滤)来进行动态注册接收者的过滤
if (registeredReceivers != null && broadcastAllowList != null) {
// if a uid whitelist was provided, remove anything in the application space that wasn't
// in it.
for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
if (owningAppId >= Process.FIRST_APPLICATION_UID
&& Arrays.binarySearch(broadcastAllowList, owningAppId) < 0) {
registeredReceivers.remove(i);
}
}
}
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.
if (isCallerSystem) {
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
isProtectedBroadcast, registeredReceivers);
}
//根据意图的flag是否有FLAG_RECEIVER_FOREGROUND来选择前台还是后台广播
final BroadcastQueue queue = broadcastQueueForIntent(intent);
//只有ACTION_PRE_BOOT_COMPLETED timeoutExempt才会为true
//这里新建的BroadcastRecord r是动态广播注册者的广播记录对象
//这里将registeredReceivers动态接受者全部传入
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers,
resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId,
allowBackgroundActivityStarts, backgroundActivityStartsToken,
timeoutExempt);
// 由于是非order的,将这个广播的平行接收者放入队列中(动态注册的广播registeredReceivers)
// 这就是所谓的平行广播的发送,发送后无需等待,一次性全部发完
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
//设置了flag FLAG_RECEIVER_REPLACE_PENDING的广播,会替换掉BroadcastQueue旧的广播
final boolean replaced = replacePending
&& (queue.replaceParallelBroadcastLocked(r) != null);
// Note: We assume resultTo is null for non-ordered broadcasts.
//如果是普通的广播,非替换的的情况
if (!replaced) {
//则将该BroadcastRecord放入BroadcastQueue的mParallelBroadcasts平行广播列表中
queue.enqueueParallelBroadcastLocked(r);
//BroadcastQueue进行广播的正常分发
queue.scheduleBroadcastsLocked();
}
//清空动态接收者,已经处理过了
registeredReceivers = null;
NR = 0;
}
=> 如果设置ordered(也称之为serialized)按顺序,不管是动态还是静态的注册者都是放入order的广播里面发送
=> 如果没有设置ordered,则只放入静态接收者。(普通的广播会有2个队列发送,一个是parallel broadcast,一个是ordered broadcast)
=> 最终不管是静态还是动态注册的广播,只要是需要order发送的都会合并到receivers中,排序是按照优先级(android:order/IntentFilter.setPriority设置的优先级)
广播发送时看到类似这样的日志:“Enqueueing ordered broadcast ***”,
需要按顺序执行,前面一个接收者执行完成后才能让后面的继续执行,同时前面的可以中断后面接收者的执行
// Merge into one list.
int ir = 0;
//处理静态接收者
if (receivers != null) {
// A special case for PACKAGE_ADDED: do not allow the package
// being added to see this broadcast. This prevents them from
// using this as a back door to get run as soon as they are
// installed. Maybe in the future we want to have a special install
// broadcast or such for apps, but we'd like to deliberately make
// this decision.
String skipPackages[] = null;
//针对ACTION_PACKAGE_ADDED/ACTION_PACKAGE_RESTARTED/ACTION_PACKAGE_DATA_CLEARED
//这类广播不允许被安装的package接收(自己接收自己安装的广播不允许),防止自启
if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
|| Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
|| Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Uri data = intent.getData();
if (data != null) {
String pkgName = data.getSchemeSpecificPart();
if (pkgName != null) {
skipPackages = new String[] { pkgName };
}
}
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
}
//将跳过的packageName从receivers中移除
if (skipPackages != null && (skipPackages.length > 0)) {
for (String skipPackage : skipPackages) {
if (skipPackage != null) {
int NT = receivers.size();
for (int it=0; it<NT; it++) {
ResolveInfo curt = (ResolveInfo)receivers.get(it);
if (curt.activityInfo.packageName.equals(skipPackage)) {
receivers.remove(it);
it--;
NT--;
}
}
}
}
}
//NT是静态接收者的个数,NR是动态接收者的个数
int NT = receivers != null ? receivers.size() : 0;
int it = 0;
ResolveInfo curt = null;
BroadcastFilter curr = null;
// 遍历静态接收者receivers和动态接收者registeredReceivers
// ir < NR代表还是存在动态接收者,由于非order的动态接收者上面已经发送完成,
// 那么这里只会是order的广播的动态接收者
while (it < NT && ir < NR) {
//取出第it个静态接收者curt
if (curt == null) {
curt = (ResolveInfo)receivers.get(it);
}
//取出ir个动态接收者curr
if (curr == null) {
curr = registeredReceivers.get(ir);
}
//动态接收者的优先级是存放在IntentFilter的mPriority, 通过IntentFilter的setPriority设置
//静态接收者的优先级是存放在ResolveInfo的priority,通过android:priority设置
if (curr.getPriority() >= curt.priority) {
// Insert this broadcast record into the final list.
// 如果动态接收者curr的优先级大于静态接收者curt的优先级,
// 则将动态接收者curr放入原来静态接收者(curt)it的位置,
// 在这之前静态接收者(curt)it已经取出来了,这里只是用动态接收者curr来填充it的位置
receivers.add(it, curr);
//动态接收者用过了则ir++, 而且将curr = null置为空,再次取下一个动态接收者
//当前receivers it的位置存放动态接收者curr
ir++;
curr = null;
//同时这里使用了list add的特性,当一个元素增加到it时,其从it到NT的元素自动+1
//于是下一个元素就是it++
it++;
//receivers新增了一个元素,于是总大小NT++
NT++;
} else {
// Skip to the next ResolveInfo in the final list.
//否则静态接收者curt的it++,同时curt = null,再次取下一个静态接收者
//当前receivers it的位置存放静态接收者curt
it++;
curt = null;
}
}
}
// 如果动态接收者还没有遍历完,说明最新的ir动态接收者curr的
// 优先级小于receivers最后一个静态接收者curt的优先级,
// 则将剩下的registeredReceivers全部加入到receivers的尾部
while (ir < NR) {
if (receivers == null) {
receivers = new ArrayList();
}
receivers.add(registeredReceivers.get(ir));
ir++;
}
//isCallerSystem(前面有解释)是否系统调用发送广播
if (isCallerSystem) {
//查看一下发送的是否保护的广播
checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
isProtectedBroadcast, receivers);
}
if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
//根据意图的flag是否有FLAG_RECEIVER_FOREGROUND来选择前台还是后台广播
BroadcastQueue queue = broadcastQueueForIntent(intent);
// 构建有序的BroadcastRecord,如果ordered = true则包含静态和动态接收者,
// 如果ordered = false则只包含静态接收者,由于静态接收者都是有序发送的,
// 故其实这个receivers全部都是有序接收的接收者
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, excludedPermissions, appOp, brOptions,
receivers, resultTo, resultCode, resultData, resultExtras,
ordered, sticky, false, userId, allowBackgroundActivityStarts,
backgroundActivityStartsToken, timeoutExempt);
//静态注册的广播在receivers中,发送ordered 按顺序接收广播
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
//设置了flag FLAG_RECEIVER_REPLACE_PENDING的广播,会替换掉BroadcastQueue旧的广播
final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
// Replaced, fire the result-to receiver.
//存在旧的oldRecord(有序的),而且resultTo不为null
if (oldRecord.resultTo != null) {
final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
try {
//则告诉原来的调用者oldRecord.callerApp,这个广播已经给cancel掉了
oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
oldRecord.intent,
Activity.RESULT_CANCELED, null, null,
false, false, oldRecord.userId);
} catch (RemoteException e) {
Slog.w(TAG, "Failure ["
+ queue.mQueueName + "] sending broadcast result of "
+ intent, e);
}
}
} else {
//将order的广播放入mDispatcher的mOrderedBroadcasts中去
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
} else {
// There was nobody interested in the broadcast, but we still want to record
// that it happened.
// 如果接收者receivers为null,而且resultTo也是null,则到这里已经没有人关注
// 如果不是发送给特定的包或者组件,而且不是只发送给动态注册的广播
if (intent.getComponent() == null && intent.getPackage() == null
&& (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
// 则记录一下这个广播的信息
addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
}
}
//返回成功发送
return ActivityManager.BROADCAST_SUCCESS;
}
前面讲的是过滤接收者,然后将信息放入广播队列中,那么广播队列是如何处理这类信息的呢?
这一节我们接下去讲解广播队列处理流程
目前有3个广播队列,一个是前台、一个是后台、一个是Offload的广播队列
其中前台广播超时时间是10s,后台是60s,Offload的广播也是60s
//ActivityManagerService.java
//前台广播队列
final BroadcastQueue mFgBroadcastQueue;
//后台广播队列
final BroadcastQueue mBgBroadcastQueue;
//Offload的广播队列(默认这个没有使用)
final BroadcastQueue mOffloadBroadcastQueue;
// Convenient for easy iteration over the queues. Foreground is first
// so that dispatch of foreground broadcasts gets precedence.
//总的广播队列
final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[3];
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
//...
// Broadcast policy parameters
final BroadcastConstants foreConstants = new BroadcastConstants(
Settings.Global.BROADCAST_FG_CONSTANTS);
//前台广播超时时间是10s
foreConstants.TIMEOUT = BROADCAST_FG_TIMEOUT;
final BroadcastConstants backConstants = new BroadcastConstants(
Settings.Global.BROADCAST_BG_CONSTANTS);
//后台广播超时时间是60s
backConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
final BroadcastConstants offloadConstants = new BroadcastConstants(
Settings.Global.BROADCAST_OFFLOAD_CONSTANTS);
offloadConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
// by default, no "slow" policy in this queue
//没有SLOW_TIME,不使用延迟策略广播
offloadConstants.SLOW_TIME = Integer.MAX_VALUE;
//默认是没有使用Offload的广播的
mEnableOffloadQueue = SystemProperties.getBoolean(
"persist.device_config.activity_manager_native_boot.offload_queue_enabled", false);
//这里的mHandler是AMS的MainHandler,优先级是THREAD_PRIORITY_FOREGROUND前台
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", foreConstants, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", backConstants, true);
mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
"offload", offloadConstants, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mBroadcastQueues[2] = mOffloadBroadcastQueue;
//...
}
这里入队列就是全部丢入广播队列BroadcastQueue的mParallelBroadcasts中
//BroadcastQueue.java
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);
enqueueBroadcastHelper(r);
}
这里多了一个中转mDispatcher(BroadcastDispatcher),放入的其实是BroadcastDispatcher的mOrderedBroadcasts中
//BroadcastQueue.java
public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
mDispatcher.enqueueOrderedBroadcastLocked(r);
enqueueBroadcastHelper(r);
}
//BroadcastDispatcher.java
void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
mOrderedBroadcasts.add(r);
}
一般外部调用(非BroadcastQueue中)分发有2种
1、scheduleBroadcastsLocked 让广播队列开始调度分发广播。如:发送广播的时候,平行广播分发、order广播分发使用的方式;注册的时候发送粘性广播也是使用这个方式
2、processNextBroadcastLocked 直接处理下一个广播。如:order广播中上一个广播处理完成后(这个比较常见,一会也会讲)、unregister的时候
scheduleBroadcastsLocked通过mHandler发送BROADCAST_INTENT_MSG -> processNextBroadcast(true)开始处理下一个广播分发
//BroadcastQueue.java
public void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
+ mQueueName + "]: current="
+ mBroadcastsScheduled);
//是否mBroadcastsScheduled正在调度中,调度中则先返回,如果出现广播堆积优先查看这个值是否一直等于true
if (mBroadcastsScheduled) {
return;
}
//通过mHandler(其looper和AMS的MainHandler是一个looper)发送BROADCAST_INTENT_MSG
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
private final class BroadcastHandler extends Handler {
public BroadcastHandler(Looper looper) {
super(looper, null, true);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG_BROADCAST, "Received BROADCAST_INTENT_MSG ["
+ mQueueName + "]");
//开始下一个广播的处理,传入的fromMsg是true
processNextBroadcast(true);
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
//广播超时的处理
broadcastTimeoutLocked(true);
}
} break;
}
}
}
//注意从handler的持有mService的锁
private void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
//此处skipOomAdj是false,也就是需要调整OomAdj
processNextBroadcastLocked(fromMsg, false);
}
}
processNextBroadcastLocked下一个广播分发
//分发下一个广播
//fromMsg:是否从handleMessage(BROADCAST_INTENT_MSG)而来
//skipOomAdj:是否需要跳过adj调整,AMS的unregisterReceiver、finishReceiver过来是true,
//BroadcastQueue过来是false
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
//BroadcastRecord广播的记录者,需要分发的广播
BroadcastRecord r;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
+ mQueueName + "]: "
+ mParallelBroadcasts.size() + " parallel broadcasts; "
+ mDispatcher.describeStateLocked());
//更新mProcessCpuMutexFree,可以继续执行updateCpuStatsNow
mService.updateCpuStats();
//如果fromMsg == ture,则设置mBroadcastsScheduled为true,允许scheduleBroadcastsLocked下一个BROADCAST_INTENT_MSG
//注意原生逻辑scheduleBroadcastsLocked和processNextBroadcastLocked都持有AMS的锁,不然mBroadcastsScheduled会出现线程冲突导致广播堆积
if (fromMsg) {
mBroadcastsScheduled = false;
}
// First, deliver any non-serialized broadcasts right away.
//第一步:先分发mParallelBroadcasts平行的广播队列
while (mParallelBroadcasts.size() > 0) {
//取出平行广播队列里面的第一个BroadcastRecord
r = mParallelBroadcasts.remove(0);
//设置BroadcastRecord r广播分发时间dispatchTime
r.dispatchTime = SystemClock.uptimeMillis();
//System.currentTimeMillis()获取的是系统时钟的时间,修改系统时间这个时间会变化
r.dispatchClockTime = System.currentTimeMillis();
//如果打开了"am"的tag会记录trace的日志
//"am", "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER,
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
//结束DELIVERY_PENDING的trace
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
System.identityHashCode(r));
//开始DELIVERY_DELIVERED的trace
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
System.identityHashCode(r));
}
final int N = r.receivers.size();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
+ mQueueName + "] " + r);
//遍历构建 BroadcastRecord 的所有receivers
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering non-ordered on [" + mQueueName + "] to registered "
+ target + ": " + r);
deliverToRegisteredReceiverLocked(r,
(BroadcastFilter) target, false, i);
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
+ mQueueName + "] " + r);
}
```java
2) deliverToRegisteredReceiverLocked分发到动态接收者
deliverToRegisteredReceiverLocked -> performReceiveLocked
```java
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
//...
//前面是各类跳过skip的场景
r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;
// If this is not being sent as an ordered broadcast, then we
// don't want to touch the fields that keep track of the current
// state of ordered broadcasts.
if (ordered) {
//order分发的时候,会有r.receiver的设置
r.receiver = filter.receiverList.receiver.asBinder();
r.curFilter = filter;
filter.receiverList.curBroadcast = r;
r.state = BroadcastRecord.CALL_IN_RECEIVE;
if (filter.receiverList.app != null) {
// Bump hosting application to no longer be in background
// scheduling class. Note that we can't do that if there
// isn't an app... but we can only be in that case for
// things that directly call the IActivityManager API, which
// are already core system stuff so don't matter for this.
r.curApp = filter.receiverList.app;
filter.receiverList.app.mReceivers.addCurReceiver(r);
mService.enqueueOomAdjTargetLocked(r.curApp);
mService.updateOomAdjPendingTargetsLocked(
OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
}
} else if (filter.receiverList.app != null) {
mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(filter.receiverList.app);
}
try {
if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
"Delivering to " + filter + " : " + r);
if (filter.receiverList.app != null && filter.receiverList.app.isInFullBackup()) {
// Skip delivery if full backup in progress
// If it's an ordered broadcast, we need to continue to the next receiver.
//全备份的app接收这才会到这里
if (ordered) {
skipReceiverLocked(r);
}
} else {
//一般跑的这里
r.receiverTime = SystemClock.uptimeMillis();
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
//接下去运行的是performReceiveLocked
//filter.receiverList.app是动态注册的callerApp, filter.receiverList.receiver是动态注册是传入的IIntentReceiver
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
// parallel broadcasts are fire-and-forget, not bookended by a call to
// finishReceiverLocked(), so we manage their activity-start token here
if (filter.receiverList.app != null
&& r.allowBackgroundActivityStarts && !r.ordered) {
postActivityStartTokenRemoval(filter.receiverList.app, r);
}
}
if (ordered) {
r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}
} catch (RemoteException e) {
Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
// Clean up ProcessRecord state related to this broadcast attempt
if (filter.receiverList.app != null) {
filter.receiverList.app.removeAllowBackgroundActivityStartsToken(r);
if (ordered) {
filter.receiverList.app.mReceivers.removeCurReceiver(r);
// Something wrong, its oom adj could be downgraded, but not in a hurry.
mService.enqueueOomAdjTargetLocked(r.curApp);
}
}
// And BroadcastRecord state related to ordered delivery, if appropriate
if (ordered) {
//异常还原
r.receiver = null;
r.curFilter = null;
filter.receiverList.curBroadcast = null;
}
}
}
performReceiveLocked返回结果给动态接收者(该函数还在广播发送时用于结果返回)
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
final IApplicationThread thread = app.getThread();
if (thread != null) {
// If we have an app thread, do the call through that so it is
// correctly ordered with other one-way calls.
try {
//调用app进程的scheduleRegisteredReceiver,分发到app进程
//scheduleRegisteredReceiver包括: updateProcessState进程状态更新/receiver.performReceive执行
//receiver调用的是LoadedApk.ReceiverDispatcher的performReceive -> mActivityThread.post一般是主线成去分发广播
thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser,
app.mState.getReportedProcState());
// TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
// DeadObjectException when the process isn't actually dead.
//} catch (DeadObjectException ex) {
// Failed to call into the process. It's dying so just let it die and move on.
// throw ex;
} catch (RemoteException ex) {
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.getPid() + "). Crashing it.");
app.scheduleCrashLocked("can't deliver broadcast");
}
throw ex;
}
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
//否者直接给到receiver的performReceive
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
IIntentReceiver在之前的文章“Android S动态广播注册流程”里面已经提到是:LoadedApk.ReceiverDispatcher得到mIIntentReceiver
//ActivityThread.java
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
//更新app的进程状态processState
updateProcessState(processState, false);
//调用IIntentReceiver的performReceive发送广播
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}
//LoadedApk.java
//LoadedApk.ReceiverDispatcher.InnerReceiver.performReceive
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
Log.wtf(TAG, "Null intent received");
rd = null;
} else {
//mDispatcher是ReceiverDispatcher
rd = mDispatcher.get();
}
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
+ " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
}
if (rd != null) {
//一般执行的是这里LoadedApk.ReceiverDispatcher的performReceive
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {
// The activity manager dispatched a broadcast to a registered
// receiver in this process, but before it could be delivered the
// receiver was unregistered. Acknowledge the broadcast on its
// behalf so that the system's broadcast sequence can continue.
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to unregistered receiver");
IActivityManager mgr = ActivityManager.getService();
try {
if (extras != null) {
extras.setAllowFds(false);
}
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
//ReceiverDispatcher.performReceive
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
if (intent == null) {
Log.wtf(TAG, "Null intent received");
} else {
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
+ " seq=" + seq + " to " + mReceiver);
}
}
//这里是通过mActivityThread线程(一般是app主线程,也可以自己传入Handler scheduler当做调度线程)
//实际是在调度线程中运行new Args的run方法
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}
=> BroadcastReceiver的onReceive执行
=> 处理完成后,调用AMS的finishReceiver,告诉系统该接受者已经处理完了
//LoadedApk.java
final class Args extends BroadcastReceiver.PendingResult {
private Intent mCurIntent;
private final boolean mOrdered;
private boolean mDispatched;
private boolean mRunCalled;
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED, ordered,
sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
mCurIntent = intent;
mOrdered = ordered;
}
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
if (ActivityThread.DEBUG_BROADCAST) {
int seq = mCurIntent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
+ " seq=" + seq + " to " + mReceiver);
Slog.i(ActivityThread.TAG, " mRegistered=" + mRegistered
+ " mOrderedHint=" + ordered);
}
final IActivityManager mgr = ActivityManager.getService();
final Intent intent = mCurIntent;
if (intent == null) {
Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
+ (mRunCalled ? ", run() has already been called" : ""));
}
mCurIntent = null;
mDispatched = true;
mRunCalled = true;
if (receiver == null || intent == null || mForgotten) {
if (mRegistered && ordered) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing null broadcast to " + mReceiver);
sendFinished(mgr);
}
return;
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
// TODO: determine at registration time if caller is
// protecting themselves with signature permission
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
mContext.getAttributionSource());
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//这里就是调用BroadcastReceiver的onReceive方法了
//如之前例子中,此时会输出"MyReceiver dynamic intent = android.intent.action.SCREEN_ON"
receiver.onReceive(mContext, intent);
} catch (Exception e) {
if (mRegistered && ordered) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing failed broadcast to " + mReceiver);
sendFinished(mgr);
}
if (mInstrumentation == null ||
!mInstrumentation.onException(mReceiver, e)) {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
throw new RuntimeException(
"Error receiving broadcast " + intent
+ " in " + mReceiver, e);
}
}
if (receiver.getPendingResult() != null) {
//结束这个接收者的广播分发,finish(BroadcastReceiver.java)->
finish();
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
};
}
}
//BroadcastReceiver.java
public final void finish() {
if (mType == TYPE_COMPONENT) {
final IActivityManager mgr = ActivityManager.getService();
if (QueuedWork.hasPendingWork()) {
// If this is a broadcast component, we need to make sure any
// queued work is complete before telling AM we are done, so
// we don't have our process killed before that. We now know
// there is pending work; put another piece of work at the end
// of the list to finish the broadcast, so we don't block this
// thread (which may be the main thread) to have it finished.
//
// Note that we don't need to use QueuedWork.addFinisher() with the
// runnable, since we know the AM is waiting for us until the
// executor gets to it.
QueuedWork.queue(new Runnable() {
@Override public void run() {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast after work to component " + mToken);
sendFinished(mgr);
}
}, false);
} else {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to component " + mToken);
//发送给静态组件后返回AMS的情况
sendFinished(mgr);
}
} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing broadcast to " + mToken);
final IActivityManager mgr = ActivityManager.getService();
//发送给动态接收者后返回AMS的情况,非order的是没有结果返回的
sendFinished(mgr);
}
}
//完成接收处理后app返回AMS
public void sendFinished(IActivityManager am) {
synchronized (this) {
if (mFinished) {
throw new IllegalStateException("Broadcast already finished");
}
mFinished = true;
try {
if (mResultExtras != null) {
mResultExtras.setAllowFds(false);
}
if (mOrderedHint) {
//order的调用的多了mResultCode、mResultData、mResultExtras、
//mAbortBroadcast(是否中断后续接收者,app使用abortBroadcast设置)
//包含静态和动态接收者
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
mAbortBroadcast, mFlags);
} else {
// This broadcast was sent to a component; it is not ordered,
// but we still need to tell the activity manager we are done.
//非order的情况,这里只会是组件接收的时候返回
am.finishReceiver(mToken, 0, null, null, false, mFlags);
}
} catch (RemoteException ex) {
}
}
}
mPendingBroadcast是正在处理的有序队列中的广播,由于进程没有启动,先挂起了。
Need to start app 的时候会设置mPendingBroadcast = r
需要先把mPendingBroadcast处理完成才能处理下一个有序队列中的广播
// Now take care of the next serialized one...
// If we are waiting for a process to come up to handle the next
// broadcast, then do nothing at this point. Just in case, we
// check that the process we're waiting for still exists.
// 分析是建议打开日志 DEBUG_BROADCAST DEBUG_BROADCAST_BACKGROUND DEBUG_BROADCAST_DEFERRAL DEBUG_BROADCAST_LIGHT
// 至于DEBUG_ALL也可以考虑打开
// Need to start app 的时候会设置mPendingBroadcast = r;
// 1. 如果进程没有启动,则首先启动进程startProcessLocked(am_proc_start)
// 2. 并将这个广播放入mPendingBroadcast中去,同时mPendingBroadcast.curApp = 下一个处理广播的进程
// 3. 当进程启动而且进行attachApplicationLocked(AMS)(am_proc_bound)/bindApplication的时候
// 调用attachApplicationLocked(AMS)->sendPendingBroadcastsLocked->processCurBroadcastLocked将该广播传递给curApp-> scheduleReceiver(ActivityThread)
// 此时也会清除mPendingBroadcast = null,代表已经处理过了
// 4. 当广播处理完成后会从app回传AMS
// 动态注册完成广播LoadedApk.ReceiverDispatcher.Args -> mActivityThread.post(args.getRunnable()) -> finish(BroadcastReceiver.java)
// deliverToRegisteredReceiverLocked/performReceiveLocked -> app.thread.scheduleRegisteredReceiver -> receiver.performReceive
// -> mActivityThread.post(args.getRunnable()) -> finish(BroadcastReceiver.java)
// 静态注册完成广播 scheduleReceiver(ActivityThread) -> RECEIVER
// -> handleReceiver(ActivityThread.java) -> finish(BroadcastReceiver.java)
// => finish/sendFinished(BroadcastReceiver.java) -> am.finishReceiver
// 5. ams收到curApp将广播处理完成,则调用r.queue.processNextBroadcastLocked继续处理下一个广播
// finishReceiver(AMS) -> r.queue.processNextBroadcastLocked(BroadcastQueue)
if (mPendingBroadcast != null) {
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
"processNextBroadcast [" + mQueueName + "]: waiting for "
+ mPendingBroadcast.curApp);
boolean isDead;
//是否存在这个进程的pid
if (mPendingBroadcast.curApp.getPid() > 0) {
synchronized (mService.mPidsSelfLocked) {
//如果存在pid,则从mPidsSelfLocked中获取这个进程的ProcessRecord proc
ProcessRecord proc = mService.mPidsSelfLocked.get(
mPendingBroadcast.curApp.getPid());
//如果proc存在,而且没有发生crash,则isDead = false
isDead = proc == null || proc.mErrorState.isCrashing();
}
} else {
//否则从mProcessList通过名字获取该进程的ProcessRecord proc
final ProcessRecord proc = mService.mProcessList.getProcessNamesLOSP().get(
mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
//如果proc存在,而且该进程正在启动中isPendingStart,则isDead = false
isDead = proc == null || !proc.isPendingStart();
}
if (!isDead) {
// It's still alive, so keep waiting
//如果mPendingBroadcast还存在,则直接返回,等待其先处理
//注意,这里等待mPendingBroadcast处理了才会有下一个广播的处理,不然一直再此等待
return;
} else {
//如果app死掉了
Slog.w(TAG, "pending app ["
+ mQueueName + "]" + mPendingBroadcast.curApp
+ " died before responding to broadcast");
mPendingBroadcast.state = BroadcastRecord.IDLE;
//下一次处理这个BroadcastRecord的nextReceiver还是这个recIdx
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
//app死掉了清除mPendingBroadcast = null, 跳过这个mPendingBroadcast
mPendingBroadcast = null;
}
}
主要是通过mDispatcher的getNextBroadcastLocked来取出有序广播队列的广播(这里就只讲解其中的mOrderedBroadcasts,如我们上面有序广播放入的地方)
总的分发时间大于210s/60snumReceivers的时间,则发出总得广播超时,并且将这个广播给finish掉
如果已经完成了广播发送,而且发送时有设置IIntentReceiver resultTo(结果返回的地方),则调用performReceiveLocked,返回结果给到resultTo
如果已经完成了广播发送,则取消该order的超时设定,输出“Finished with ordered broadcast”类似日志
boolean looped = false;
do {
final long now = SystemClock.uptimeMillis();
//取得mAlarmBroadcasts(alarm挂起的广播)、mDeferredBroadcasts(如果存在order的广播在处理,这类延迟广播会按照deferUntil进行延迟)、
// mOrderedBroadcasts 有序广播队列,依次取出来
r = mDispatcher.getNextBroadcastLocked(now);
if (r == null) {
// No more broadcasts are deliverable right now, so all done!
//如果存在延迟的广播mDeferredBroadcasts,则重新下一次调度scheduleBroadcastsLocked
//不过一般上面BroadcastRecord r都取得出来(存在延迟的广播mDeferredBroadcasts, getNextBroadcastLocked得出来),
// 也就是这里相当于没啥作用
mDispatcher.scheduleDeferralCheckLocked(false);
synchronized (mService.mAppProfiler.mProfilerLock) {
//将AMS所有挂起的gc进程mProcessesToGc进行按顺序的gc
mService.mAppProfiler.scheduleAppGcsLPf();
}
if (looped && !skipOomAdj) {
// If we had finished the last ordered broadcast, then
// make sure all processes have correct oom and sched
// adjustments.
//adj调整,原因是启动了receiver
mService.updateOomAdjPendingTargetsLocked(
OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
}
// when we have no more ordered broadcast on this queue, stop logging
//现在已经没有mOrderedBroadcasts 有序广播队列, 则停止log的输出mLogLatencyMetrics = false
if (mService.mUserController.mBootCompleted && mLogLatencyMetrics) {
mLogLatencyMetrics = false;
}
//结束本次processNextBroadcastLocked
return;
}
//是否需要强制结束recevie
boolean forceReceive = false;
// Ensure that even if something goes awry with the timeout
// detection, we catch "hung" broadcasts here, discard them,
// and continue to make progress.
//
// This is only done if the system is ready so that early-stage receivers
// don't get executed with timeouts; and of course other timeout-
// exempt broadcasts are ignored.
//numReceivers接收者的个数
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
//systemReady之后mService.mProcessesReady = true
//timeoutExempt只有ACTION_PRE_BOOT_COMPLETED才会设置为true
//r.dispatchTime是开始分发该BroadcastRecord r的时间
if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
//如果当前时间now > r.dispatchTime + (2 * mConstants.TIMEOUT(10s/60s) * numReceivers)
//也就是总的分发时间大于2*10s/60s*numReceivers的时间,则告知这个广播出现anr
//isAnrDeferrable是mtk加入的是否需要跳过anr的逻辑
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers)) &&
/// M: ANR Debug Mechanism
!mService.mAnrManager.isAnrDeferrable()) {
Slog.w(TAG, "Hung broadcast ["
+ mQueueName + "] discarded after timeout failure:"
+ " now=" + now
+ " dispatchTime=" + r.dispatchTime
+ " startTime=" + r.receiverTime
+ " intent=" + r.intent
+ " numReceivers=" + numReceivers
+ " nextReceiver=" + r.nextReceiver
+ " state=" + r.state);
broadcastTimeoutLocked(false); // forcibly finish this broadcast
//设置强制结束recevie (forceReceive = true)
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
if (r.state != BroadcastRecord.IDLE) {
if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
"processNextBroadcast("
+ mQueueName + ") called when not idle (state="
+ r.state + ")");
return;
}
// Is the current broadcast is done for any reason?
// 如果没有r.receivers 或者 r.nextReceiver已经遍历完成最后一个了
// 或者强制结束forceReceive,
// 或者resultAbort为true(bortBroadcast(应用进程) -> finishReceiver(AMS)-> r.queue.finishReceiverLocked(BroadcastQueue))
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
// Send the final result if requested
//是否有resultTo,如果有将结果回传resultTo
if (r.resultTo != null) {
boolean sendResult = true;
// if this was part of a split/deferral complex, update the refcount and only
// send the completion when we clear all of them
if (r.splitToken != 0) {
int newCount = mSplitRefcounts.get(r.splitToken) - 1;
if (newCount == 0) {
// done! clear out this record's bookkeeping and deliver
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST,
"Sending broadcast completion for split token "
+ r.splitToken + " : " + r.intent.getAction());
}
mSplitRefcounts.delete(r.splitToken);
} else {
// still have some split broadcast records in flight; update refcount
// and hold off on the callback
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST,
"Result refcount now " + newCount + " for split token "
+ r.splitToken + " : " + r.intent.getAction()
+ " - not sending completion yet");
}
sendResult = false;
mSplitRefcounts.put(r.splitToken, newCount);
}
}
if (sendResult) {
if (r.callerApp != null) {
mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(
r.callerApp);
}
try {
if (DEBUG_BROADCAST) {
Slog.i(TAG_BROADCAST, "Finishing broadcast [" + mQueueName + "] "
+ r.intent.getAction() + " app=" + r.callerApp);
}
//将结果返回给app
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
// Set this to null so that the reference
// (local and remote) isn't kept in the mBroadcastHistory.
r.resultTo = null;
} catch (RemoteException e) {
r.resultTo = null;
Slog.w(TAG, "Failure ["
+ mQueueName + "] sending broadcast result of "
+ r.intent, e);
}
}
}
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
//取消广播超时
cancelBroadcastTimeoutLocked();
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
"Finished with ordered broadcast " + r);
// ... and on to the next...
//添加到广播历史中去,代表完成了
addBroadcastToHistoryLocked(r);
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
//完成odered的广播后,在retireBroadcastLocked中设置mCurrentBroadcast = null(一般在r == mCurrentBroadcast时)
mDispatcher.retireBroadcastLocked(r);
//r == null继续while循环,取出下一个广播
r = null;
looped = true;
continue;
}
// Check whether the next receiver is under deferral policy, and handle that
// accordingly. If the current broadcast was already part of deferred-delivery
// tracking, we know that it must now be deliverable as-is without re-deferral.
// addDeferredBroadcast的时候会将deferred设置成ture,
// 如果这个广播没有进行延迟,则判断一下是否需要延迟
if (!r.deferred) {
//获取下一个nextReceiver的uid
final int receiverUid = r.getReceiverUid(r.receivers.get(r.nextReceiver));
//如果
if (mDispatcher.isDeferringLocked(receiverUid)) {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Next receiver in " + r + " uid " + receiverUid
+ " at " + r.nextReceiver + " is under deferral");
}
// If this is the only (remaining) receiver in the broadcast, "splitting"
// doesn't make sense -- just defer it as-is and retire it as the
// currently active outgoing broadcast.
BroadcastRecord defer;
// 下一个Receiver将延迟,再下一个Receiver已经没有了
if (r.nextReceiver + 1 == numReceivers) {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Sole receiver of " + r
+ " is under deferral; setting aside and proceeding");
}
defer = r;
// 下一个Receiver将延迟,再下一个Receiver已经没有了,
// 则在retireBroadcastLocked中设置mCurrentBroadcast = null(一般在r == mCurrentBroadcast时)
mDispatcher.retireBroadcastLocked(r);
} else {
// Nontrivial case; split out 'uid's receivers to a new broadcast record
// and defer that, then loop and pick up continuing delivery of the current
// record (now absent those receivers).
// The split operation is guaranteed to match at least at 'nextReceiver'
defer = r.splitRecipientsLocked(receiverUid, r.nextReceiver);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Post split:");
Slog.i(TAG_BROADCAST, "Original broadcast receivers:");
for (int i = 0; i < r.receivers.size(); i++) {
Slog.i(TAG_BROADCAST, " " + r.receivers.get(i));
}
Slog.i(TAG_BROADCAST, "Split receivers:");
for (int i = 0; i < defer.receivers.size(); i++) {
Slog.i(TAG_BROADCAST, " " + defer.receivers.get(i));
}
}
// Track completion refcount as well if relevant
if (r.resultTo != null) {
int token = r.splitToken;
if (token == 0) {
// first split of this record; refcount for 'r' and 'deferred'
r.splitToken = defer.splitToken = nextSplitTokenLocked();
mSplitRefcounts.put(r.splitToken, 2);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST,
"Broadcast needs split refcount; using new token "
+ r.splitToken);
}
} else {
// new split from an already-refcounted situation; increment count
final int curCount = mSplitRefcounts.get(token);
if (DEBUG_BROADCAST_DEFERRAL) {
if (curCount == 0) {
Slog.wtf(TAG_BROADCAST,
"Split refcount is zero with token for " + r);
}
}
mSplitRefcounts.put(token, curCount + 1);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "New split count for token " + token
+ " is " + (curCount + 1));
}
}
}
}
//将defer添加到延迟广播中,按照uid放入
mDispatcher.addDeferredBroadcast(receiverUid, defer);
//r == null会继续while循环
r = null;
looped = true;
continue;
}
}
} while (r == null);
//BroadcastDispatcher.java
//获取下一个处理的广播BroadcastRecord next,上面mDispatcher.getNextBroadcastLocked调用
//这里除了mOrderedBroadcasts有序广播队列,还多了mAlarmBroadcasts(alarm设置的)、mDeferredBroadcasts(延迟广播)的概念
public BroadcastRecord getNextBroadcastLocked(final long now) {
//如果当前mCurrentBroadcast还在处理,则直接返回mCurrentBroadcast
if (mCurrentBroadcast != null) {
return mCurrentBroadcast;
}
//是否有oder的广播,如果有,则someQueued = true
final boolean someQueued = !mOrderedBroadcasts.isEmpty();
BroadcastRecord next = null;
//mAlarmBroadcasts不为空的时候
if (!mAlarmBroadcasts.isEmpty()) {
// 首先取出的就是mAlarmBroadcasts中的Deferrals d
// 然后取出BroadcastRecord next = d.broadcasts.remove(0)
next = popLocked(mAlarmBroadcasts);
if (DEBUG_BROADCAST_DEFERRAL && next != null) {
Slog.i(TAG, "Next broadcast from alarm targets: " + next);
}
}
//如果next为null,而且mDeferredBroadcasts还有内容
if (next == null && !mDeferredBroadcasts.isEmpty()) {
// We're going to deliver either:
// 1. the next "overdue" deferral; or
// 2. the next ordinary ordered broadcast; *or*
// 3. the next not-yet-overdue deferral.
for (int i = 0; i < mDeferredBroadcasts.size(); i++) {
Deferrals d = mDeferredBroadcasts.get(i);
//查看一下当前now是否小于d.deferUntil(延迟分发时间,默认是延迟5s)
//而且someQueued为true,就是有order的时候才break?(跳过这个延迟广播)
if (now < d.deferUntil && someQueued) {
// stop looking when we haven't hit the next time-out boundary
// but only if we have un-deferred broadcasts waiting,
// otherwise we can deliver whatever deferred broadcast
// is next available.
break;
}
if (d.broadcasts.size() > 0) {
//取出next
next = d.broadcasts.remove(0);
// apply deferral-interval decay policy and move this uid's
// deferred broadcasts down in the delivery queue accordingly
//将这个Deferrals d从mDeferredBroadcasts移除,代表已经处理了
mDeferredBroadcasts.remove(i); // already 'd'
//deferredBy*0.75在赋值给deferredBy(第一次deferredBy是5s)
d.deferredBy = calculateDeferral(d.deferredBy);
//延迟时间deferUntil + deferredBy*0.75,再给新的Deferrals d
d.deferUntil += d.deferredBy;
//重新根据deferUntil排序放入mDeferredBroadcasts
//貌似d.broadcasts如果此时为null,不需要再次将d加入mDeferredBroadcasts了吧?
insertLocked(mDeferredBroadcasts, d);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG, "Next broadcast from deferrals " + next
+ ", deferUntil now " + d.deferUntil);
}
break;
}
}
}
//如果next还是null,而且someQueued=true(有oder的广播)
if (next == null && someQueued) {
//则取出order的广播
next = mOrderedBroadcasts.remove(0);
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG, "Next broadcast from main queue: " + next);
}
}
//当前正在处理的广播
mCurrentBroadcast = next;
return next;
}
// Get the next receiver...
// 正常取出一个广播r != null
//先将nextReceiver赋值给recIdx,然后nextReceiver++,下一次进来nextReceiver就不会时当前这个了
int recIdx = r.nextReceiver++;
// Keep track of when this receiver started, and make sure there
// is a timeout message pending to kill it if need be.
//设置receiver接受时间receiverTime
r.receiverTime = SystemClock.uptimeMillis();
if (recIdx == 0) {
//如果recIdx是第一个,这将receiverTime设置给dispatchTime(这个广播的分发时间)
r.dispatchTime = r.receiverTime;
//设置分发的系统时间(修改系统时间这个时间会变化)
r.dispatchClockTime = System.currentTimeMillis();
if (mLogLatencyMetrics) {
//输出日志到FrameworkStatsLog中
FrameworkStatsLog.write(
FrameworkStatsLog.BROADCAST_DISPATCH_LATENCY_REPORTED,
r.dispatchClockTime - r.enqueueClockTime);
}
//trace相关
if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
System.identityHashCode(r));
Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
System.identityHashCode(r));
}
//输出开始发送order的广播
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
+ mQueueName + "] " + r);
}
//如果还没有设置超时时间,此处设置超时时间
if (! mPendingBroadcastTimeoutMessage) {
//单个广播超时时间是10s(前台)或者60s(后台广播)
long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Submitting BROADCAST_TIMEOUT_MSG ["
+ mQueueName + "] for " + r + " at " + timeoutTime);
setBroadcastTimeoutLocked(timeoutTime);
}
final BroadcastOptions brOptions = r.options;
//获取下一个接受者
final Object nextReceiver = r.receivers.get(recIdx);
//如果这个nextReceiver为BroadcastFilter类型(动态注册广播接收者)
// BroadcastRecord的receivers还有另一种类型ResolveInfo,是从PMS中查询得到的静态注册广播类型
if (nextReceiver instanceof BroadcastFilter) {
// Simple case: this is a registered receiver who gets
// a direct call.
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Delivering ordered ["
+ mQueueName + "] to registered "
+ filter + ": " + r);
//发送给动态注册的广播
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
//如果r.receiver == null(没有正在执行的广播)
//而且该广播是非order的
if (r.receiver == null || !r.ordered) {
// The receiver has already finished, so schedule to
// process the next one.
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
+ mQueueName + "]: ordered="
+ r.ordered + " receiver=" + r.receiver);
r.state = BroadcastRecord.IDLE;
//已经发出去执行了,无需等待,直接处理下一个
scheduleBroadcastsLocked();
} else {
if (filter.receiverList != null) {
maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
// r is guaranteed ordered at this point, so we know finishReceiverLocked()
// will get a callback and handle the activity start token lifecycle.
}
}
//直接返回,代表本次完成,一次处理一个广播中的nextReceiver
return;
}
跳过的逻辑较多,
这里注意一下“Background execution not allowed”,如果flag设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND则无法让后台接收,
或者getComponent/getPackage都为null,而且没有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,而且没有requiredPermissions,
则无法发送给后台的进程(进程状态procState>=PROCESS_STATE_TRANSIENT_BACKGROUND(8)属于广播的后台进程)
// Hard case: need to instantiate the receiver, possibly
// starting its application process to host it.
//静态广播的处理
ResolveInfo info =
(ResolveInfo)nextReceiver;
ComponentName component = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
//注意这里是静态广播接收跳过的逻辑,动态注册跳过的逻辑是在deliverToRegisteredReceiverLocked中
boolean skip = false;
//判断是否需要跳过
//sdk的一些判断
if (brOptions != null &&
(info.activityInfo.applicationInfo.targetSdkVersion
< brOptions.getMinManifestReceiverApiLevel() ||
info.activityInfo.applicationInfo.targetSdkVersion
> brOptions.getMaxManifestReceiverApiLevel())) {
Slog.w(TAG, "Target SDK mismatch: receiver " + info.activityInfo
+ " targets " + info.activityInfo.applicationInfo.targetSdkVersion
+ " but delivery restricted to ["
+ brOptions.getMinManifestReceiverApiLevel() + ", "
+ brOptions.getMaxManifestReceiverApiLevel()
+ "] broadcasting " + broadcastDescription(r, component));
skip = true;
}
//查看发送者的uid和接受者的uid是否一样,或者是否系统uid,确定一些是否两者有设定关联关系association
//默认返回是true
if (!skip && !mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid,
component.getPackageName(), info.activityInfo.applicationInfo.uid)) {
Slog.w(TAG, "Association not allowed: broadcasting "
+ broadcastDescription(r, component));
skip = true;
}
if (!skip) {
//看一下意图防火墙mIntentFirewall是否有block该发送行为
skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
if (skip) {
Slog.w(TAG, "Firewall blocked: broadcasting "
+ broadcastDescription(r, component));
}
}
//权限相关的的检查
int perm = mService.checkComponentPermission(info.activityInfo.permission,
r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
info.activityInfo.exported);
if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
if (!info.activityInfo.exported) {
Slog.w(TAG, "Permission Denial: broadcasting "
+ broadcastDescription(r, component)
+ " is not exported from uid " + info.activityInfo.applicationInfo.uid);
} else {
Slog.w(TAG, "Permission Denial: broadcasting "
+ broadcastDescription(r, component)
+ " requires " + info.activityInfo.permission);
}
skip = true;
} else if (!skip && info.activityInfo.permission != null) {
final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
if (opCode != AppOpsManager.OP_NONE && mService.getAppOpsManager().noteOpNoThrow(opCode,
r.callingUid, r.callerPackage, r.callerFeatureId,
"Broadcast delivered to " + info.activityInfo.name)
!= AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "Appop Denial: broadcasting "
+ broadcastDescription(r, component)
+ " requires appop " + AppOpsManager.permissionToOp(
info.activityInfo.permission));
skip = true;
}
}
boolean isSingleton = false;
try {
isSingleton = mService.isSingleton(info.activityInfo.processName,
info.activityInfo.applicationInfo,
info.activityInfo.name, info.activityInfo.flags);
} catch (SecurityException e) {
Slog.w(TAG, e.getMessage());
skip = true;
}
if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
if (ActivityManager.checkUidPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS,
info.activityInfo.applicationInfo.uid)
!= PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
+ " requests FLAG_SINGLE_USER, but app does not hold "
+ android.Manifest.permission.INTERACT_ACROSS_USERS);
skip = true;
}
}
if (!skip && info.activityInfo.applicationInfo.isInstantApp()
&& r.callingUid != info.activityInfo.applicationInfo.uid) {
Slog.w(TAG, "Instant App Denial: receiving "
+ r.intent
+ " to " + component.flattenToShortString()
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")"
+ " Instant Apps do not support manifest receivers");
skip = true;
}
if (!skip && r.callerInstantApp
&& (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
&& r.callingUid != info.activityInfo.applicationInfo.uid) {
Slog.w(TAG, "Instant App Denial: receiving "
+ r.intent
+ " to " + component.flattenToShortString()
+ " requires receiver have visibleToInstantApps set"
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")");
skip = true;
}
//crash的app则直接跳过
if (r.curApp != null && r.curApp.mErrorState.isCrashing()) {
// If the target process is crashing, just skip it.
Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
+ " to " + r.curApp + ": process crashing");
skip = true;
}
if (!skip) {
boolean isAvailable = false;
try {
isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
info.activityInfo.packageName,
UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
} catch (Exception e) {
// all such failures mean we skip this receiver
Slog.w(TAG, "Exception getting recipient info for "
+ info.activityInfo.packageName, e);
}
//确定是否可用
if (!isAvailable) {
Slog.w(TAG_BROADCAST,
"Skipping delivery to " + info.activityInfo.packageName + " / "
+ info.activityInfo.applicationInfo.uid
+ " : package no longer available");
skip = true;
}
}
// If permissions need a review before any of the app components can run, we drop
// the broadcast and if the calling app is in the foreground and the broadcast is
// explicit we launch the review UI passing it a pending intent to send the skipped
// broadcast.
if (!skip) {
//判断是否需要权限来启动,如果需要则跳过(如果调用者是前台,而且发送到特定组件,则启动权限申请的ui界面)
if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
info.activityInfo.packageName, UserHandle.getUserId(
info.activityInfo.applicationInfo.uid))) {
Slog.w(TAG_BROADCAST,
"Skipping delivery: permission review required for "
+ broadcastDescription(r, component));
skip = true;
}
}
// This is safe to do even if we are skipping the broadcast, and we need
// this information now to evaluate whether it is going to be allowed to run.
//接收者的uid
final int receiverUid = info.activityInfo.applicationInfo.uid;
// If it's a singleton, it needs to be the same app or a special app
if (r.callingUid != Process.SYSTEM_UID && isSingleton
&& mService.isValidSingletonCall(r.callingUid, receiverUid)) {
info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
}
//接受者的进程名字
String targetProcess = info.activityInfo.processName;
//接受者的进程ProcessRecord app,这个可能为null,也就是进程未启动
ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
info.activityInfo.applicationInfo.uid);
if (!skip) {
final int allowed = mService.getAppStartModeLOSP(
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
/*
//进程状态,只有小于8才会被认为可以接收广播(不带getComponent、getPackage)
public static final boolean isProcStateBackground(int procState) {
return procState >= PROCESS_STATE_TRANSIENT_BACKGROUND;
}
//PROCESS_STATE_TRANSIENT_BACKGROUND后台临时的一个状态(一般的含义,如toasts)
//1.如果设置了getForcingToImportant不为null(调用AMS的setProcessImportant设置),会设置该状态,
//而且adj是用户可感知的PERCEPTIBLE_APP_ADJ,例如toasts是这种情况(NotificationManagerService中调用setProcessImportant)
//2.AMS的mBackupTargets是该app,且其adj大于BACKUP_APP_ADJ,会设置该值
//3.service服务依赖:如果设置了BIND_NOT_FOREGROUND(非前台绑定)而且没有设置BIND_IMPORTANT_BACKGROUND(绑定重要后台)的时候,
//且客户端状态优先级小于该值时,会设置该值
TRANSIENT_BACKGROUND = 8,
*/
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
// We won't allow this receiver to be launched if the app has been
// completely disabled from launches, or it was not explicitly sent
// to it and the app is in a state that should not receive it
// (depending on how getAppStartModeLOSP has determined that).
if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
Slog.w(TAG, "Background execution disabled: receiving "
+ r.intent + " to "
+ component.flattenToShortString());
skip = true;
//如果flag设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND则无法让后台接收
//或者getComponent/getPackage都为null,而且没有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,而且没有requiredPermissions
//如ACTION_BOOT_COMPLETED是有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,所以静态广播无需权限就可以直接接收
} else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
|| (r.intent.getComponent() == null
&& r.intent.getPackage() == null
&& ((r.intent.getFlags()
& Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
&& !isSignaturePerm(r.requiredPermissions))) {
mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
component.getPackageName());
Slog.w(TAG, "Background execution not allowed: receiving "
+ r.intent + " to "
+ component.flattenToShortString());
skip = true;
}
}
}
if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
&& !mService.mUserController
.isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
0 /* flags */)) {
skip = true;
Slog.w(TAG,
"Skipping delivery to " + info.activityInfo.packageName + " / "
+ info.activityInfo.applicationInfo.uid + " : user is not running");
}
//处理不包含的权限excludedPermissions
if (!skip && r.excludedPermissions != null && r.excludedPermissions.length > 0) {
for (int i = 0; i < r.excludedPermissions.length; i++) {
String excludedPermission = r.excludedPermissions[i];
try {
perm = AppGlobals.getPackageManager()
.checkPermission(excludedPermission,
info.activityInfo.applicationInfo.packageName,
UserHandle
.getUserId(info.activityInfo.applicationInfo.uid));
} catch (RemoteException e) {
perm = PackageManager.PERMISSION_DENIED;
}
int appOp = AppOpsManager.permissionToOpCode(excludedPermission);
if (appOp != AppOpsManager.OP_NONE) {
// When there is an app op associated with the permission,
// skip when both the permission and the app op are
// granted.
if ((perm == PackageManager.PERMISSION_GRANTED) && (
mService.getAppOpsManager().checkOpNoThrow(appOp,
info.activityInfo.applicationInfo.uid,
info.activityInfo.packageName)
== AppOpsManager.MODE_ALLOWED)) {
skip = true;
break;
}
} else {
// When there is no app op associated with the permission,
// skip when permission is granted.
if (perm == PackageManager.PERMISSION_GRANTED) {
skip = true;
break;
}
}
}
}
//处理需要包含的权限requiredPermission
if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
r.requiredPermissions != null && r.requiredPermissions.length > 0) {
for (int i = 0; i < r.requiredPermissions.length; i++) {
String requiredPermission = r.requiredPermissions[i];
try {
perm = AppGlobals.getPackageManager().
checkPermission(requiredPermission,
info.activityInfo.applicationInfo.packageName,
UserHandle
.getUserId(info.activityInfo.applicationInfo.uid));
} catch (RemoteException e) {
perm = PackageManager.PERMISSION_DENIED;
}
if (perm != PackageManager.PERMISSION_GRANTED) {
Slog.w(TAG, "Permission Denial: receiving "
+ r.intent + " to "
+ component.flattenToShortString()
+ " requires " + requiredPermission
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")");
skip = true;
break;
}
int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp) {
if (!noteOpForManifestReceiver(appOp, r, info, component)) {
skip = true;
break;
}
}
}
}
if (!skip && r.appOp != AppOpsManager.OP_NONE) {
//AppOps相关判断
if (!noteOpForManifestReceiver(r.appOp, r, info, component)) {
skip = true;
}
}
//上面都是各类判断是否需要跳过的逻辑skip
if (skip) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Skipping delivery of ordered [" + mQueueName + "] "
+ r + " for reason described above");
//如果需要跳过,标定当前r.delivery[recIdx]为skipped
r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
//跳过的时候清空r.receiver = null
r.receiver = null;
r.curFilter = null;
r.state = BroadcastRecord.IDLE;
//静态广播跳过++
r.manifestSkipCount++;
//继续下一个分发
scheduleBroadcastsLocked();
return;
}
ps: 注意一下,此处广播记录的状态设置成app接收“r.state = BroadcastRecord.APP_RECEIVE”,
设置当前接收的组件r.curComponent = component
//静态广播Count执行++
r.manifestCount++;
//标定当前r.delivery[recIdx]为分发DELIVERED
r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
//状态修改成app接收APP_RECEIVE,后面该receive finishReceiver返回的时候APP_RECEIVE或BroadcastRecord.CALL_DONE_RECEIVE才会继续处理下一个
r.state = BroadcastRecord.APP_RECEIVE;
//当前接收组件curComponent
r.curComponent = component;
//当前的receiver
r.curReceiver = info.activityInfo;
if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
+ info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
+ receiverUid);
}
final boolean isActivityCapable =
(brOptions != null && brOptions.getTemporaryAppAllowlistDuration() > 0);
maybeScheduleTempAllowlistLocked(receiverUid, r, brOptions);
// Report that a component is used for explicit broadcasts.
if (r.intent.getComponent() != null && r.curComponent != null
&& !TextUtils.equals(r.curComponent.getPackageName(), r.callerPackage)) {
mService.mUsageStatsService.reportEvent(
r.curComponent.getPackageName(), r.userId, Event.APP_COMPONENT_USED);
}
// Broadcast is being executed, its package can't be stopped.
try {
//设置包的stop状态是false(需要启动改应用了,包不再是stop了)
AppGlobals.getPackageManager().setPackageStoppedState(
r.curComponent.getPackageName(), false, r.userId);
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
Slog.w(TAG, "Failed trying to unstop package "
+ r.curComponent.getPackageName() + ": " + e);
}
// Is this receiver's application already running?
//如果app之前已经启动
if (app != null && app.getThread() != null && !app.isKilled()) {
try {
app.addPackage(info.activityInfo.packageName,
info.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats);
maybeAddAllowBackgroundActivityStartsToken(app, r);
//则直接发送该广播到app中
processCurBroadcastLocked(r, app);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when sending broadcast to "
+ r.curComponent, e);
} catch (RuntimeException e) {
Slog.wtf(TAG, "Failed sending broadcast to "
+ r.curComponent + " with " + r.intent, e);
// If some unexpected exception happened, just skip
// this broadcast. At this point we are not in the call
// from a client, so throwing an exception out from here
// will crash the entire system instead of just whoever
// sent the broadcast.
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
r.state = BroadcastRecord.IDLE;
return;
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
//发送给静态注册者的函数processCurBroadcastLocked
private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app) throws RemoteException {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Process cur broadcast " + r + " for app " + app);
final IApplicationThread thread = app.getThread();
if (thread == null) {
throw new RemoteException();
}
if (app.isInFullBackup()) {
skipReceiverLocked(r);
return;
}
//processCurBroadcastLocked的时候,会有r.receiver的设置
r.receiver = thread.asBinder();
r.curApp = app;
final ProcessReceiverRecord prr = app.mReceivers;
prr.addCurReceiver(r);
app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
mService.updateLruProcessLocked(app, false, null);
// Make sure the oom adj score is updated before delivering the broadcast.
// Force an update, even if there are other pending requests, overall it still saves time,
// because time(updateOomAdj(N apps)) <= N * time(updateOomAdj(1 app)).
mService.enqueueOomAdjTargetLocked(app);
mService.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
// Tell the application to launch this receiver.
//r.curComponent是发送给静态接收者的时候设置的组件名字
r.intent.setComponent(r.curComponent);
boolean started = false;
try {
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
"Delivering to component " + r.curComponent
+ ": " + r);
mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
//发送给app主线程的scheduleReceiver
thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
mService.compatibilityInfoForPackage(r.curReceiver.applicationInfo),
r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
app.mState.getReportedProcState());
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Process cur broadcast " + r + " DELIVERED for app " + app);
started = true;
} finally {
if (!started) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Process cur broadcast " + r + ": NOT STARTED!");
//没有启动成功,还原状态
r.receiver = null;
r.curApp = null;
prr.removeCurReceiver(r);
}
}
}
//ActivityThread.java
//APP的接受者,在主线程中运行
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
//...
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
//处理广播接收者
handleReceiver((ReceiverData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
//...
}
private void handleReceiver(ReceiverData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
//获取相关组件
String component = data.intent.getComponent().getClassName();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
IActivityManager mgr = ActivityManager.getService();
Application app;
BroadcastReceiver receiver;
ContextImpl context;
//新建一个静态接收者的实例BroadcastReceiver
try {
app = packageInfo.makeApplication(false, mInstrumentation);
context = (ContextImpl) app.getBaseContext();
if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
}
if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
final String attributionTag = data.info.attributionTags[0];
context = (ContextImpl) context.createAttributionContext(attributionTag);
}
java.lang.ClassLoader cl = context.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess(
isProtectedComponent(data.info) || isProtectedBroadcast(data.intent),
context.getAttributionSource());
data.setExtrasClassLoader(cl);
//通过class loader,新建一个接收者的实例,(BroadcastReceiver) cl.loadClass(className).newInstance()
//如实例化MyReceiver
receiver = packageInfo.getAppFactory()
.instantiateReceiver(cl, data.info.name, data.intent);
} catch (Exception e) {
if (DEBUG_BROADCAST) Slog.i(TAG,
"Finishing failed broadcast to " + data.intent.getComponent());
data.sendFinished(mgr);
throw new RuntimeException(
"Unable to instantiate receiver " + component
+ ": " + e.toString(), e);
}
try {
if (localLOGV) Slog.v(
TAG, "Performing receive of " + data.intent
+ ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + packageInfo.getPackageName()
+ ", comp=" + data.intent.getComponent().toShortString()
+ ", dir=" + packageInfo.getAppDir());
sCurrentBroadcastIntent.set(data.intent);
receiver.setPendingResult(data);
//执行app定义的onReceive方法,如执行MyReceiver的onReceive方法
receiver.onReceive(context.getReceiverRestrictedContext(),
data.intent);
} catch (Exception e) {
if (DEBUG_BROADCAST) Slog.i(TAG,
"Finishing failed broadcast to " + data.intent.getComponent());
data.sendFinished(mgr);
if (!mInstrumentation.onException(receiver, e)) {
throw new RuntimeException(
"Unable to start receiver " + component
+ ": " + e.toString(), e);
}
} finally {
sCurrentBroadcastIntent.set(null);
}
if (receiver.getPendingResult() != null) {
//BroadcastReceiver.PendingResul(ReceiverData继承PendingResul)的finish
//具体过程和“4.4.1 mParallelBroadcasts平行广播的分发”是类似的
data.finish();
}
}
// Not running -- get it started, to be executed when the app comes up.
//否则第一步,我们需要先启动该进程
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Need to start app ["
+ mQueueName + "] " + targetProcess + " for broadcast " + r);
//启动进程ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE(延迟敏感的)标签用于确定fork进程时是否需要使用usap
r.curApp = mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
new HostingRecord("broadcast", r.curComponent), isActivityCapable
? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
(r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
if (r.curApp == null) {
// Ah, this recipient is unavailable. Finish it if necessary,
// and mark the broadcast record as ready for the next.
//当无法启动app的时候,完成这个广播BroadcastRecord r的分发finishReceiverLocked
Slog.w(TAG, "Unable to launch app "
+ info.activityInfo.applicationInfo.packageName + "/"
+ receiverUid + " for broadcast "
+ r.intent + ": process is bad");
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
r.state = BroadcastRecord.IDLE;
return;
}
maybeAddAllowBackgroundActivityStartsToken(r.curApp, r);
// Need to start app 需要先启动该进程会设置mPendingBroadcast = r;
//启动进程后会调用attachApplicationLocked(AMS)、bindApplication(IApplicationThread)
//attachApplicationLocked(AMS)-> sendPendingBroadcastsLocked 会处理mPendingBroadcast
mPendingBroadcast = r;
//mPendingBroadcastRecvIndex是当前需要处理recevie的recIdx
mPendingBroadcastRecvIndex = recIdx;
}
=> mService.startProcessLocked启动进程后,
会调用ActivityThread的main方法:创建main loop,调用thread.attach,Looper.loop开始消息队列的循环
//ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
// Install selective syscall interception
AndroidOs.install();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
// Call per-process mainline module initialization.
//google main line的模块初始化
initializeMainlineModules();
//设置该进程刚刚创建,名字是""
//在handleBindApplication之后app才会设置成对应的进程名字processName
Process.setArgV0("" );
//准备主线程,此处H mH = new H();才能从Looper.myLooper()获取主线程的sMainLooper
Looper.prepareMainLooper();
// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//这里是接下去的流程
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//开始loop的循环,此时ActivityThread主线程mH的消息队列才开始分发
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
//附着方法attach
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mConfigurationController = new ConfigurationController(this);
mSystemThread = system;
if (!system) {
//app进程的逻辑
android.ddm.DdmHandleAppName.setAppName("" ,
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//调用的是AMS的attachApplication
mgr.attachApplication(mAppThread, startSeq);
//...
} else {
// Don't set application object here -- if the system crashes,
// we can't display an alert, we just want to die die die.
//系统进程的逻辑
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
mInstrumentation = new Instrumentation();
mInstrumentation.basicInit(this);
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
//...
}
=> AMS收到app的attachApplication,查看是否有挂起的广播isPendingBroadcastProcessLocked,
如果有则让广播队列处理该app挂起的广播sendPendingBroadcastsLocked
//ActivityManagerService.java
//从app调用的attachApplication(附着在应用)方法
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
//attachApplicationLocked,加个Locked,这类方法代表需要上锁才能调用
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
//...
//绑定pid到ProcessRecord,用于死亡回调AppDeathRecipient
if (DEBUG_ALL) Slog.v(
TAG, "Binding process pid " + pid + " to record " + app);
final String processName = app.processName;
try {
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.setDeathRecipient(adr);
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
mProcessList.startProcessLocked(app,
new HostingRecord("link fail", processName),
ZYGOTE_POLICY_FLAG_EMPTY);
return false;
}
//这个就是event log中经常出现的"am_proc_bound",代表进程创建后,app进程回调AMS绑定了该app进程
EventLogTags.writeAmProcBound(app.userId, pid, app.processName);
//进程信息记录ProcessRecord app的初始化
//...
//同时这里还会从system_server回传APP进程,去绑定应用bindApplication
thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.getCompat(), getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions,
app.getDisabledCompatChanges(), serializedSystemFontMap);
//...
// 调用ActivityTaskManagerService的attachApplication(activity是否需要运行)
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// 调用ActiveServices的attachApplication(services是否需要运行)
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
badApp = true;
}
}
// 看一下是否有挂起的广播需要运行
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
//向广播队列告知,有挂起的进程启动
didSomething |= sendPendingBroadcastsLocked(app);
checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
} catch (Exception e) {
// If the app died trying to launch the receiver we declare it 'bad'
Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
badApp = true;
}
}
//...
return true;
}
//BroadcastQueue.java
//遍历所有的广播队列,看一下是否有挂起的广播
boolean isPendingBroadcastProcessLocked(int pid) {
return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
|| mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
|| mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(pid);
}
//查看该pid是否有挂起的广播
public boolean isPendingBroadcastProcessLocked(int pid) {
return mPendingBroadcast != null && mPendingBroadcast.curApp.getPid() == pid;
}
//向广播队列告知,有挂起的进程启动
// The app just attached; send any pending broadcasts that it should receive
boolean sendPendingBroadcastsLocked(ProcessRecord app) {
boolean didSomething = false;
for (BroadcastQueue queue : mBroadcastQueues) {
didSomething |= queue.sendPendingBroadcastsLocked(app);
}
return didSomething;
}
=> 广播队列处理挂起的进程sendPendingBroadcastsLocked -> processCurBroadcastLocked,
并清除mPendingBroadcast = null,广播分发可以继续下去
=> processCurBroadcastLocked将广播发送给该app的curComponent
=> processCurBroadcastLocked(系统进程BroadcastQueue.java)将该广播传递给curApp-> scheduleReceiver(app进程ActivityThread)
-> RECEIVER -> handleReceiver(ActivityThread.java) -> finish(BroadcastReceiver.java) -> finish/sendFinished(BroadcastReceiver.java)
-> am.finishReceiver(再次回到系统进程AMS)
//BroadcastQueue.java
// attachApplicationLocked(AMS) -> sendPendingBroadcastsLocked(AMS/BroadcastQueue)
// 进程启动的时候会清除 mPendingBroadcast
public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
boolean didSomething = false;
final BroadcastRecord br = mPendingBroadcast;
if (br != null && br.curApp.getPid() > 0 && br.curApp.getPid() == app.getPid()) {
if (br.curApp != app) {
Slog.e(TAG, "App mismatch when sending pending broadcast to "
+ app.processName + ", intended target is " + br.curApp.processName);
return false;
}
try {
//发送给pending的广播时候会清除 mPendingBroadcast = nul
mPendingBroadcast = null;
//"章节4.4.7"中已经讲过这个函数,就是发送给该app的curComponent(静态接收者组件名字)
processCurBroadcastLocked(br, app);
didSomething = true;
} catch (Exception e) {
Slog.w(TAG, "Exception in new application when starting receiver "
+ br.curComponent.flattenToShortString(), e);
logBroadcastReceiverDiscardLocked(br);
finishReceiverLocked(br, br.resultCode, br.resultData,
br.resultExtras, br.resultAbort, false);
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
br.state = BroadcastRecord.IDLE;
throw new RuntimeException(e.getMessage());
}
}
return didSomething;
}
我们接着讲AMS的finishReceiver,这个是广播接受者接收完成后,回传AMS的方法
//ActivityManagerService.java
public void finishReceiver(IBinder who, int resultCode, String resultData,
Bundle resultExtras, boolean resultAbort, int flags) {
//打印该广播接受者完成处理的日志
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
//...
final long origId = Binder.clearCallingIdentity();
try {
boolean doNext = false;
BroadcastRecord r;
BroadcastQueue queue;
synchronized(this) {
//查看广播队列属于前台还是后台
if (isOnOffloadQueue(flags)) {
queue = mOffloadBroadcastQueue;
} else {
queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
? mFgBroadcastQueue : mBgBroadcastQueue;
}
//看一下对应的BroadcastRecord是谁
r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
//如果BroadcastRecord r存在,则告知广播队列BroadcastQueue,该广播接收者已经完成了finishReceiverLocked
doNext = r.queue.finishReceiverLocked(r, resultCode,
resultData, resultExtras, resultAbort, true);
}
//如果doNext正常返回true(上一个正常处理完成返回的就是true)
if (doNext) {
//开始下一个广播接受者的调度,这里就是order的按顺序的核心
r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
}
// updateOomAdjLocked() will be done here
trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
finishReceiverLocked是广播完成时调用,到这里广播的流程基本上就讲完了
//BroadcastQueue.java
public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
final int state = r.state;
final ActivityInfo receiver = r.curReceiver;
final long finishTime = SystemClock.uptimeMillis();
final long elapsed = finishTime - r.receiverTime;
//app状态变成IDLE
r.state = BroadcastRecord.IDLE;
//如果是执行静态注册广播接收的逻辑,这里一般情况是BroadcastRecord.APP_RECEIVE(无超时/无异常情况时)
if (state == BroadcastRecord.IDLE) {
Slog.w(TAG_BROADCAST, "finishReceiver [" + mQueueName + "] called but state is IDLE");
}
if (r.allowBackgroundActivityStarts && r.curApp != null) {
if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) {
// if the receiver has run for more than allowed bg activity start timeout,
// just remove the token for this process now and we're done
r.curApp.removeAllowBackgroundActivityStartsToken(r);
} else {
// It gets more time; post the removal to happen at the appropriate moment
postActivityStartTokenRemoval(r.curApp, r);
}
}
// If we're abandoning this broadcast before any receivers were actually spun up,
// nextReceiver is zero; in which case time-to-process bookkeeping doesn't apply.
if (r.nextReceiver > 0) {
r.duration[r.nextReceiver - 1] = elapsed;
}
// if this receiver was slow, impose deferral policy on the app. This will kick in
// when processNextBroadcastLocked() next finds this uid as a receiver identity.
//timeoutExempt只有ACTION_PRE_BOOT_COMPLETED才会设置为true,也就是一般会进来
if (!r.timeoutExempt) {
// r.curApp can be null if finish has raced with process death - benign
// edge case, and we just ignore it because we're already cleaning up
// as expected.
if (r.curApp != null
&& mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
// Core system packages are exempt from deferral policy
//看一下是否需要加入延迟广播里面
if (!UserHandle.isCore(r.curApp.uid)) {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
+ " was slow: " + receiver + " br=" + r);
}
mDispatcher.startDeferring(r.curApp.uid);
} else {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
+ " receiver was slow but not deferring: "
+ receiver + " br=" + r);
}
}
}
} else {
if (DEBUG_BROADCAST_DEFERRAL) {
Slog.i(TAG_BROADCAST, "Finished broadcast " + r.intent.getAction()
+ " is exempt from deferral policy");
}
}
//结束的时候r.receiver = null
r.receiver = null;
r.intent.setComponent(null);
if (r.curApp != null && r.curApp.mReceivers.hasCurReceiver(r)) {
r.curApp.mReceivers.removeCurReceiver(r);
mService.enqueueOomAdjTargetLocked(r.curApp);
}
if (r.curFilter != null) {
r.curFilter.receiverList.curBroadcast = null;
}
r.curFilter = null;
r.curReceiver = null;
r.curApp = null;
//正常的完成广播接收的时候会清除mPendingBroadcast = nul
mPendingBroadcast = null;
r.resultCode = resultCode;
r.resultData = resultData;
r.resultExtras = resultExtras;
// bortBroadcast(应用进程) -> finishReceiver(AMS)-> r.queue.finishReceiverLocked(BroadcastQueue)
// 只要这个广播没有设置不能中断,则order的广播,优先级在前面的可以中断后续的广播接收
if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
r.resultAbort = resultAbort;
} else {
r.resultAbort = false;
}
// If we want to wait behind services *AND* we're finishing the head/
// active broadcast on its queue
if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
&& r.queue.mDispatcher.getActiveBroadcastLocked() == r) {
ActivityInfo nextReceiver;
if (r.nextReceiver < r.receivers.size()) {
Object obj = r.receivers.get(r.nextReceiver);
nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
} else {
nextReceiver = null;
}
// Don't do this if the next receive is in the same process as the current one.
if (receiver == null || nextReceiver == null
|| receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
|| !receiver.processName.equals(nextReceiver.processName)) {
// In this case, we are ready to process the next receiver for the current broadcast,
//?but are on a queue that would like to wait for services to finish before moving
// on. If there are background services currently starting, then we will go into a
// special state where we hold off on continuing this broadcast until they are done.
//如果该uid的进程有正在启动的后台服务mStartingBackground,则等待后台服务启动完成再继续
if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString());
r.state = BroadcastRecord.WAITING_SERVICES;
return false;
}
}
}
r.curComponent = null;
// We will process the next receiver right now if this is finishing
// an app receiver (which is always asynchronous) or after we have
// come back from calling a receiver.
//发送给静态注册者的时候一般是APP_RECEIVE,发送给动态注册者的时候一般是CALL_DONE_RECEIVE
return state == BroadcastRecord.APP_RECEIVE
|| state == BroadcastRecord.CALL_DONE_RECEIVE;
}
从上面的文章基本上可以知道广播是干什么的,广播的流程是怎么样的。
一般广播的应用有3类:
1、针对高配置的设备:VIP广播,给一些关键的进程,关键的广播,放入特定的队列,不会由于本身广播队列阻塞了其广播分发,
达到比较高效的分发
2、针对低配置的设备:
=> 延迟广播,间隔分发广播等。主要是广播如平行广播一次性发给所有进程,会导致系统负担;
或者是发送给静态注册者需要启动应用,启动多个应用的时候会导致系统负载过重,可以将类似广播延迟分发。
(这个总负载还是一样的,只是分散开来,降低持续卡顿情况,至于偶发的峰值卡顿还是存在,需要别的方法配合)
场景如开机、切换语言等
=> 限制广播:如在特定场景限制启动,限制接收等行为,降低系统负载。
(这类方法效果立竿见影,不过场景需要非常慎重,不然导致功能使用可能出现异常)
=> 其它应用:特定场景修改超时时间,让用户感知的anr减少;针对用户不可见的anr,看一下是否需要用户感知等;接受者优先级调整等。
3、各类广播无法接收问题的解决等(可以考虑动态打开一些基本的调试广播开关DEBUG_BROADCAST DEBUG_BROADCAST_BACKGROUND DEBUG_BROADCAST_DEFERRAL DEBUG_BROADCAST_LIGHT DEBUG_BACKGROUND_CHECK)
了解广播的流程,实现上述内容一般都大概心里有底,会比较快速的做出相应的方案。