Android 12.0 通知--PendingIntent源码分析-LMLPHP

结论: PendingIntent 是延迟触发的一种 Intent , 通过上图的过程看,PendingIntent 的执行,是一种跨进程通信.首先创建PendingIntent对象时,就把该对象定义到 ActivityManagerService, 到执行 PengdingIntent 动作时, 也是在 ActivityManagerService 找到 目标PengdingIntent, 从而执行相应操作.

1. PendingIntent 在 Android 通知中的使用场景

使用场景: Android 通知的 setContentIntent() 需要传入 PendingIntent , 即当点击通知时,执行 intent 的动作.如下例子:


Intent intent = new Intent(this, MainActivity1.class);

//1.获取能启动 Activity 的PendingIntent 对象 
 
PendingIntent pendingIntent =  PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_MUTABLE); 
 
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id")
        .setSmallIcon(R.drawable.notification_icon) 
        .setContentTitle("Notification Title")                
        .setContentText("Notification content text...")               
    
        .setContentIntent(pendingIntent) //2.设置PendingIntent
 
        .setPriority(NotificationCompat.PRIORITY_DEFAULT);
        
        NotificationManager notificationManager = (NotificationManager.class);
        NotificationChannel channel = new NotificationChannel("11", "channel-name", NotificationManager.IMPORTANCE_DEFAULT);
        notificationManager.createNotificationChannel(channel);
        notificationManager.notify(11, builder.build());

2. PendingIntent 的使用

(1) PendingIntent 的获取

核心源码路径 : frameworks/base/core/java/android/app/PendingIntent.java

1. 跳转到 Activity ,指定一个 Activity
 public static PendingIntent getActivity(Context context, int requestCode,
            Intent intent, @Flags int flags)

2. 跳转到 Activity , 指定多各 Activity 
 public static PendingIntent getActivities(Context context, int requestCode,
            @NonNull Intent[] intents, @Flags int flags)

3. 打开 广播 组件
public static PendingIntent getBroadcast(Context context, int requestCode,
            @NonNull Intent intent, @Flags int flags) 

4. 打开 服务 组件
 public static PendingIntent getService(Context context, int requestCode,
            @NonNull Intent intent, @Flags int flags) 

 (2) 参数说明:

  • requestCode : 发送方设定的请求码.
  • intent : 要启动的意图.(注意: 需要使用显示 Intent , 即明确将要启动的组件名).
  • flags :   主要是方便后续管理所有的PendingIntent对象,可选的标签如下:

    1) FLAG_ONE_SHOT :  PendingIntent 只能使用一次.该标签后面还能说明.

    2) FLAG_NO_CREATE : 不创建 PendingIntent, 如果PendingIntent存在,则返回null.

    3) FLAG_CANCEL_CURRENT : 如果所描述 PendingIntent 已存在,则在生成新的 PendingIntent 之前,取消当前已存在的PendingIntent.

    4) FLAG_UPDATE_CURRENT : 如果所描述 PendingIntent 已存在,则保留该对象,并用新的数据更新该对象.

    5) FLAG_IMMUTABLE : PendingIntent 不可变.

    6) FLAG_MUTABLE : PendingIntent 可变.

3. PendingIntent 的源码分析

以上图通知的代码为例子,说明创建 PendingIntent 对象的过程.

PendingIntent pendingIntent =  PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_MUTABLE); 
(1) 调用 PendingIntent 中的 getActivity() , 源码如下 :
核心源码路径 : frameworks/base/core/java/android/app/PendingIntent.java
 
 public static PendingIntent getActivity(Context context, int requestCode,
            Intent intent, @Flags int flags) {
        return getActivity(context, requestCode, intent, flags, null);
    }


 public static PendingIntent getActivity(Context context, int requestCode,
            @NonNull Intent intent, @Flags int flags, @Nullable Bundle options) {
        // Some tests only mock Context.getUserId(), so fallback to the id Context.getUser() is null
        final UserHandle user = context.getUser();
        return getActivityAsUser(context, requestCode, intent, flags, options,
                user != null ? user : UserHandle.of(context.getUserId()));
    }

 public static PendingIntent getActivityAsUser(Context context, int requestCode,
            @NonNull Intent intent, int flags, Bundle options, UserHandle user) {
        String packageName = context.getPackageName(); //获取包名 
        String resolvedType = intent.resolveTypeIfNeeded(context.getContentResolver());
        checkFlags(flags, packageName); 
        try {
            intent.migrateExtraStreamToClipData(context);
            intent.prepareToLeaveProcess(context);
            IIntentSender target =
                ActivityManager.getService().getIntentSenderWithFeature(
                    INTENT_SENDER_ACTIVITY, packageName,
                    context.getAttributionTag(), null, null, requestCode, new Intent[] { intent },
                    resolvedType != null ? new String[] { resolvedType } : null,
                    flags, options, user.getIdentifier()); //获取 IntentSender
            return target != null ? new PendingIntent(target) : null; //创建 PendingIntent 对象,
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

       上面最终会调用到 getActivityAsUser( ) , 其中 创建 PendingIntent 对象的时候,需要传入 IIntentSender target 的对象, 而该对象是从 ActivityManagerService.getIntentSenderWithFeature( ) 获取,其中的第一个参数,这里传递的是 INTENT_SENDER_ACTIVITY , 代码获取启动 activity 的PendingIntent , 其他的类型如下:

  • ActivityManager. INTENT_SENDER_ACTIVITY
  • ActivityManager. INTENT_SENDER_ACTIVITY_RESULT
  • ActivityManager. INTENT_SENDER_SERVICE
  • ActivityManager. INTENT_SENDER_FORGROUND_SERVICE
  • ActivityManager. INTENT_SENDER_BROADCAST

(2) ActivityManagerService.getIntentSenderWithFeature( )的源码如下:

核心源码路径 : frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 public IIntentSender getIntentSenderWithFeature(int type, String packageName, String featureId,
            IBinder token, String resultWho, int requestCode, Intent[] intents,
            String[] resolvedTypes, int flags, Bundle bOptions, int userId) {
        enforceNotIsolatedCaller("getIntentSender");

        return getIntentSenderWithFeatureAsApp(type, packageName, featureId, token, resultWho,
                requestCode, intents, resolvedTypes, flags, bOptions, userId,
                Binder.getCallingUid());
    }


public IIntentSender getIntentSenderWithFeatureAsApp(int type, String packageName,
            String featureId, IBinder token, String resultWho, int requestCode, Intent[] intents,
            String[] resolvedTypes, int flags, Bundle bOptions, int userId, int owningUid) {
        
        if (intents != null) {
            if (intents.length < 1) { //必须指定至少一个intent
                throw new IllegalArgumentException("Intents array length must be >= 1");
            }
            for (int i=0; i<intents.length; i++) {
                Intent intent = intents[i];
                if (intent != null) {
                    if (intent.hasFileDescriptors()) { //不能携带文件描述符
                        throw new IllegalArgumentException("File descriptors passed in Intent");
                    }
                    //广播类的PendingIntent中,定义的intent不能携带 FLAG_RECEIVER_BOOT_UPGRADE(启动并升级) 的标签
                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
                        throw new IllegalArgumentException(
                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
                    }
                    intents[i] = new Intent(intent);
                }
            }
            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
                throw new IllegalArgumentException(
                        "Intent array length does not match resolvedTypes length");
            }
        }
        if (bOptions != null) {
            if (bOptions.hasFileDescriptors()) {
                throw new IllegalArgumentException("File descriptors passed in options");
            }
        }

        int origUserId = userId;
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), owningUid, userId,
                type == ActivityManager.INTENT_SENDER_BROADCAST,
                ALLOW_NON_FULL, "getIntentSender", null);
        if (origUserId == UserHandle.USER_CURRENT) {
            // We don't want to evaluate this until the pending intent is
            // actually executed.  However, we do want to always do the
            // security checking for it above.
            userId = UserHandle.USER_CURRENT;
        }
        try {
            if (owningUid != 0 && owningUid != SYSTEM_UID) {
                final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
                        MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(owningUid));
                if (!UserHandle.isSameApp(owningUid, uid)) {
                    String msg = "Permission Denial: getIntentSender() from pid="
                            + Binder.getCallingPid()
                            + ", uid=" + owningUid
                            + ", (need uid=" + uid + ")"
                            + " is not allowed to send as package " + packageName;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
            }

            if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
                return mAtmInternal.getIntentSender(type, packageName, featureId, owningUid,
                        userId, token, resultWho, requestCode, intents, resolvedTypes, flags,
                        bOptions);
            }
            // 继续调用 PendingIntentController 类的getIntentSender()来获取IIntentSender
            return mPendingIntentController.getIntentSender(type, packageName, featureId,
                    owningUid, userId, token, resultWho, requestCode, intents, resolvedTypes,
                    flags, bOptions);
        } catch (RemoteException e) {
            throw new SecurityException(e);
        }
    }

       通过对 intent 等信息的过滤后,函数的最后继续调用 PendingIntentController 类的 getIntentSender() 方法来获取 IIntentSender 对象(请看下面(4)), 在介绍 getIntentSender( )之前,首先介绍一下,系统把每个 PendingIntent 对象都封装成 PendingIntentRecord 对象,然后通过PendingIntentController 对象来统一管理 PendingIntentRecord 对象,从而达到管理 PendingIntent .

Android 12.0 通知--PendingIntent源码分析-LMLPHP

 (3) PendingIntentRecord 对象源码分析

核心代码路径 : frameworks/base/services/core/java/com/android/server/am/PendingIntentRecord.java


public final class PendingIntentRecord extends IIntentSender.Stub {


    final PendingIntentController controller;
    final Key key;  //内部类对象
    final int uid;
    public final WeakReference<PendingIntentRecord> ref; 
    boolean sent = false;
    boolean canceled = false;


// PendingIntentRecord对象的内部类,主要用于存储PendingIntent 对象中的参数

 final static class Key {
        final int type;
        final String packageName;
        final String featureId;
        final IBinder activity;
        final String who;
        final int requestCode;
        final Intent requestIntent; //获取最后一个intent,一般情况下都是指定一个intent
        final String requestResolvedType;
        final SafeActivityOptions options;
        Intent[] allIntents;    //获取所有的intent,如果设定了多个intent
        String[] allResolvedTypes;
        final int flags;
        final int hashCode;
        final int userId;

(4)  PendingIntentController 类简介, 以及 getIntentSender() 方法来获取 IIntentSender 对象

核心路径:  frameworks/base/services/core/java/com/android/server/am/PendingIntentController.java


/**
 * 该类主要的职责就是协助 ActivityManagerService 管理所有的 PendingIntent
 */

public class PendingIntentController {



    /** 保存所有可用的IntentSenderRecord 对象. */
    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
            = new HashMap<>();

               ......


public PendingIntentRecord getIntentSender(int type, String packageName,
            @Nullable String featureId, int callingUid, int userId, IBinder token, String resultWho,
            int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle bOptions) {
        synchronized (mLock) {
            if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSender(): uid=" + callingUid);


            if (intents != null) {
                for (int i = 0; i < intents.length; i++) {
                    intents[i].setDefusable(true);
                }
            }
            Bundle.setDefusable(bOptions, true);
           
           //根据PendingIntent中设置的flag,从而决定该PendingIntent对象是取消或更新等操作

            final boolean noCreate = (flags & PendingIntent.FLAG_NO_CREATE) != 0;
            final boolean cancelCurrent = (flags & PendingIntent.FLAG_CANCEL_CURRENT) != 0;
            final boolean updateCurrent = (flags & PendingIntent.FLAG_UPDATE_CURRENT) != 0;
            flags &= ~(PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_CANCEL_CURRENT
                    | PendingIntent.FLAG_UPDATE_CURRENT);
           
            //把PendingIntent的信息传入PendingIntentRecord内部类Key对象中

            PendingIntentRecord.Key key = new PendingIntentRecord.Key(type, packageName, featureId,
                    token, resultWho, requestCode, intents, resolvedTypes, flags,
                    SafeActivityOptions.fromBundle(bOptions), userId);
            WeakReference<PendingIntentRecord> ref;
            ref = mIntentSenderRecords.get(key);
            PendingIntentRecord rec = ref != null ? ref.get() : null;
           //遍历 列表,如果该 PendingIntentRecord 已经存在,则需要根据 flags 来进一步处理
            if (rec != null) {
                if (!cancelCurrent) { 
                    // 没有设置 PendingIntent.FLAG_CANCEL_CURRENT,即 PendingIntentRecord 不取消
                    if (updateCurrent) {
                           //设置了PendingIntent.FLAG_UPDATE_CURRENT ,则更新 PendingIntentRecord 
                        if (rec.key.requestIntent != null) {
                            rec.key.requestIntent.replaceExtras(intents != null ?
                                    intents[intents.length - 1] : null);
                        }
                        if (intents != null) {
                            intents[intents.length - 1] = rec.key.requestIntent;
                            rec.key.allIntents = intents;
                            rec.key.allResolvedTypes = resolvedTypes;
                        } else {
                            rec.key.allIntents = null;
                            rec.key.allResolvedTypes = null;
                        }
                    }
                    // 更新完毕,返回 PendingIntentRecord
                    return rec;
                }
               // 设置 PendingIntent.FLAG_CANCEL_CURRENT,即 PendingIntent 取消
                makeIntentSenderCanceled(rec);
                mIntentSenderRecords.remove(key);
                decrementUidStatLocked(rec);
            }
            if (noCreate) {
                return rec;
            }
           //如果列表中没有找到匹配的PendingIntentRecord,则创建新的PendingIntentRecord
            rec = new PendingIntentRecord(this, key, callingUid);
           //把新的PendingIntentRecord,存入列表
            mIntentSenderRecords.put(key, rec.ref);
            incrementUidStatLocked(rec);
            // 返回新的PendingIntentRecord
            return rec;
        }
    }


//取消 PendingIntent 
 private void makeIntentSenderCanceled(PendingIntentRecord rec) {
        rec.canceled = true; //设置 取消 标志,这样下次遍历列表时,直接跳出if判断,如上
        final RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
        if (callbacks != null) {
            final Message m = PooledLambda.obtainMessage(
                    PendingIntentController::handlePendingIntentCancelled, this, callbacks);
            mH.sendMessage(m);
        }
        final AlarmManagerInternal ami = LocalServices.getService(AlarmManagerInternal.class);
        ami.remove(new PendingIntent(rec));
    }

      到此,  不管是新创建的,还是更新的PendingIntentRecord ,这样原路返回给  ActivityManagerService.java, 最后到 PendingIntent.java,即前面 new PendingIntent(target) 中需要的 IIntentSender 对象, 这样就成功创建了PendingIndent.过程如下:

Android 12.0 通知--PendingIntent源码分析-LMLPHP

3.  PendingIntent.send() 源码分析

       在通知的场景中,第三方应用通过监听到新通知,获取到通知携带的PendingIntent 对象,然后执行PendingIntent.send()方法,即可实现PendingIntent中intent指定的动作.send() 经过一系列的调用,最终调用 sendAndReturnResult() 方法,源码分析如下:

public int sendAndReturnResult(Context context, int code, @Nullable Intent intent,
            @Nullable OnFinished onFinished, @Nullable Handler handler,
            @Nullable String requiredPermission, @Nullable Bundle options)
            throws CanceledException {
        try {
            String resolvedType = intent != null ?
                    intent.resolveTypeIfNeeded(context.getContentResolver())
                    : null;

            if (context != null && isActivity()) {

                ActivityOptions activityOptions = options != null ? new ActivityOptions(options)
                        : ActivityOptions.makeBasic();
                activityOptions.setCallerDisplayId(context.getDisplayId());
                options = activityOptions.toBundle();
            }
            //通过ActivityManagerService的sendIntentSender()获取IIntentSender,其中mTarget是PendingIntentRecord
            return ActivityManager.getService().sendIntentSender(
                    mTarget, mWhitelistToken, code, intent, resolvedType,
                    onFinished != null
                            ? new FinishedDispatcher(this, onFinished, handler)
                            : null,
                    requiredPermission, options);
        } catch (RemoteException e) {
            throw new CanceledException(e);
        }
    }

(1) ActivityManagerService.sendIntentSender() 源码分析

public int sendIntentSender(IIntentSender target, IBinder allowlistToken, int code,
            Intent intent, String resolvedType,
            IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
        if (target instanceof PendingIntentRecord) {
            //继续调用PendingIntentRecord.sendWithResult()
            return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
                    allowlistToken, finishedReceiver, requiredPermission, options);
        } else {
            if (intent == null) {
                Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
                intent = new Intent(Intent.ACTION_MAIN);
            }
            try {
                target.send(code, intent, resolvedType, allowlistToken, null,
                        requiredPermission, options);
            } catch (RemoteException e) {
            }
   
            if (finishedReceiver != null) {
                try {
                    finishedReceiver.performReceive(intent, 0,
                            null, null, false, false, UserHandle.getCallingUserId());
                } catch (RemoteException e) {
                }
            }
            return 0;
        }
    }

(2) PendingIntentRecord.sendWithResult() 源码分析

sendWithResult()最终调用 sendInner() 方法,源码如下:

public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken,
            IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo,
            String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) {
        if (intent != null) intent.setDefusable(true);
        if (options != null) options.setDefusable(true);

        TempAllowListDuration duration = null;
        Intent finalIntent = null;
        Intent[] allIntents = null;
        String[] allResolvedTypes = null;
        SafeActivityOptions mergedOptions = null;
        synchronized (controller.mLock) {
            if (canceled) {
                return ActivityManager.START_CANCELED;
            }

            sent = true;
           //检查PendingIntent标签,如果设置了FLAG_ONE_SHOT,表示清除该PendingIntent对象,
           //即把 IIntentSender 对象清除,接着再从列表中清除
            if ((key.flags & PendingIntent.FLAG_ONE_SHOT) != 0) {
                controller.cancelIntentSender(this, true);
            }
           
           //获取最后一个Intent,对于只设置一个intent的场景也适用
            finalIntent = key.requestIntent != null ? new Intent(key.requestIntent) : new Intent();

            final boolean immutable = (key.flags & PendingIntent.FLAG_IMMUTABLE) != 0;
            if (!immutable) {
                if (intent != null) {
                    int changes = finalIntent.fillIn(intent, key.flags);
                    if ((changes & Intent.FILL_IN_DATA) == 0) {
                        resolvedType = key.requestResolvedType;
                    }
                } else {
                    resolvedType = key.requestResolvedType;
                }
                flagsMask &= ~Intent.IMMUTABLE_FLAGS;
                flagsValues &= flagsMask;
                finalIntent.setFlags((finalIntent.getFlags() & ~flagsMask) | flagsValues);
            } else {
                resolvedType = key.requestResolvedType;
            }


            final ActivityOptions opts = ActivityOptions.fromBundle(options);
            if (opts != null) {
                finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
            }

            mergedOptions = key.options;
            if (mergedOptions == null) {
                mergedOptions = new SafeActivityOptions(opts);
            } else {
                mergedOptions.setCallerOptions(opts);
            }

            if (mAllowlistDuration != null) {
                duration = mAllowlistDuration.get(allowlistToken);
            }

            if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY
                    && key.allIntents != null && key.allIntents.length > 1) {
                allIntents = new Intent[key.allIntents.length];
                allResolvedTypes = new String[key.allIntents.length];
                System.arraycopy(key.allIntents, 0, allIntents, 0, key.allIntents.length);
                if (key.allResolvedTypes != null) {
                    System.arraycopy(key.allResolvedTypes, 0, allResolvedTypes, 0,
                            key.allResolvedTypes.length);
                }
                allIntents[allIntents.length - 1] = finalIntent;
                allResolvedTypes[allResolvedTypes.length - 1] = resolvedType;
            }

        }

        final int callingUid = Binder.getCallingUid();
        final int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();

        int res = START_SUCCESS;
        try {
            if (duration != null) {
                StringBuilder tag = new StringBuilder(64);
                tag.append("setPendingIntentAllowlistDuration,reason:");
                tag.append(duration.reason == null ? "" : duration.reason);
                tag.append(",pendingintent:");
                UserHandle.formatUid(tag, callingUid);
                tag.append(":");
                if (finalIntent.getAction() != null) {
                    tag.append(finalIntent.getAction());
                } else if (finalIntent.getComponent() != null) {
                    finalIntent.getComponent().appendShortString(tag);
                } else if (finalIntent.getData() != null) {
                    tag.append(finalIntent.getData().toSafeString());
                }
                controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid,
                        uid, duration.duration, duration.type, duration.reasonCode, tag.toString());
            } else if (key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE
                    && options != null) {
                BroadcastOptions brOptions = new BroadcastOptions(options);
                if (brOptions.getTemporaryAppAllowlistDuration() > 0) {
                    controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid,
                            uid, brOptions.getTemporaryAppAllowlistDuration(),
                            brOptions.getTemporaryAppAllowlistType(),
                            brOptions.getTemporaryAppAllowlistReasonCode(),
                            brOptions.getTemporaryAppAllowlistReason());
                }
            }

            boolean sendFinish = finishedReceiver != null;
            int userId = key.userId;
            if (userId == UserHandle.USER_CURRENT) {
                userId = controller.mUserController.getCurrentOrTargetUserId();
            }
            //暂时允许接收者和服务从后台打开活动
            
            final boolean allowTrampoline = uid != callingUid
                    && controller.mAtmInternal.isUidForeground(callingUid);

            //根据不同类型的PendingIntent,执行不相应的操作
            switch (key.type) {
                case ActivityManager.INTENT_SENDER_ACTIVITY:
                    try {

                        if (key.allIntents != null && key.allIntents.length > 1) {
                          //启动通过ActivityManagerService 启动Activity,
                            res = controller.mAtmInternal.startActivitiesInPackage(
                                    uid, callingPid, callingUid, key.packageName, key.featureId,
                                    allIntents, allResolvedTypes, resultTo, mergedOptions, userId,
                                    false /* validateIncomingUser */,
                                    this /* originatingPendingIntent */,
                                    mAllowBgActivityStartsForActivitySender.contains(
                                            allowlistToken));
                        } else {
                            res = controller.mAtmInternal.startActivityInPackage(uid, callingPid,
                                    callingUid, key.packageName, key.featureId, finalIntent,
                                    resolvedType, resultTo, resultWho, requestCode, 0,
                                    mergedOptions, userId, null, "PendingIntentRecord",
                                    false /* validateIncomingUser */,
                                    this /* originatingPendingIntent */,
                                    mAllowBgActivityStartsForActivitySender.contains(
                                            allowlistToken));
                        }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startActivity intent", e);
                    }
                    break;
                case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
                    controller.mAtmInternal.sendActivityResult(-1, key.activity, key.who,
                                key.requestCode, code, finalIntent);
                    break;
                case ActivityManager.INTENT_SENDER_BROADCAST:
                    try {
                        final boolean allowedByToken =
                                mAllowBgActivityStartsForBroadcastSender.contains(allowlistToken);
                        final IBinder bgStartsToken = (allowedByToken) ? allowlistToken : null;
                       //启动通过ActivityManagerService 发送广播,
                        int sent = controller.mAmInternal.broadcastIntentInPackage(key.packageName,
                                key.featureId, uid, callingUid, callingPid, finalIntent,
                                resolvedType, finishedReceiver, code, null, null,
                                requiredPermission, options, (finishedReceiver != null), false,
                                userId, allowedByToken || allowTrampoline, bgStartsToken);
                        if (sent == ActivityManager.BROADCAST_SUCCESS) {
                            sendFinish = false;
                        }
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startActivity intent", e);
                    }
                    break;
                case ActivityManager.INTENT_SENDER_SERVICE:
                case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
                    try {
                        final boolean allowedByToken =
                                mAllowBgActivityStartsForServiceSender.contains(allowlistToken);
                        final IBinder bgStartsToken = (allowedByToken) ? allowlistToken : null;

                        //启动通过ActivityManagerService 启动Service
                        controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType,
                                key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
                                key.packageName, key.featureId, userId,
                                allowedByToken || allowTrampoline, bgStartsToken);
                    } catch (RuntimeException e) {
                        Slog.w(TAG, "Unable to send startService intent", e);
                    } catch (TransactionTooLargeException e) {
                        res = ActivityManager.START_CANCELED;
                    }
                    break;
            }

            if (sendFinish && res != ActivityManager.START_CANCELED) {
                try {
                    finishedReceiver.performReceive(new Intent(finalIntent), 0,
                            null, null, false, false, key.userId);
                } catch (RemoteException e) {
                }
            }
        } finally {
            Binder.restoreCallingIdentity(origId);
        }

        return res;
    }

PendingIntent 最终还是通过 ActivityManagerService 来启动相应的组件.到此, Activity类型的 PendingIntent 就分析完毕了.

01-13 16:58