android13#startForegroundService

476 阅读23分钟

1.简介

1.1.Q

  • 对比下startService和startForegroundService的区别.
  • 前台服务里,如果不调用startForeground启动前台通知,服务为啥会crash,如何做到的?

1.2.A

  • startService是启动一个普通的服务,startForegroundService是启动一个前台服务,必须带一个前台通知,好让用户知道有这么一个服务在运行中,服务不容易被杀死。
  • 参考2.3,启动前台服务后,会给对应的服务new一个错误异常放入map里,后续读取这个异常提示用户,非必须
  • 5.4.4启动前台服务的时候,会调用5.9的方法post一个30秒后处理的超时msg
  • 参考6.4,启动前台通知,会移除2.3末尾添加的异常map,接着走到5.6 ,5.7里会移除上边添加的延迟30秒的msg

1.3.启动流程

  • 2.2到2.3,intent的验证以及初始化,

  • 完事到4.1,caller的过滤,

  • 到5.1,会调用5.2的方法查找服务信息,中间一些权限检查等,

  • 最后调用5.4的方法进行最终的启动,启动成功返回组件名。

  • 5.4.1里更新服务状态为前台服务,调用5.4.2方法拉起服务。

  • 服务超时msg的设置见5.4.4,具体逻辑见5.9,

  • msg取消见5.7(调用startForeground方法启动前台通知就会走这里)

2.ContextImpl.java

2.1.startService

    public ComponentName startService(Intent service) {
        warnIfCallingFromSystemProcess();
        //见2.3,参数为false
        return startServiceCommon(service, false, mUser);
    }

2.2.startForegroundService

    public ComponentName startForegroundService(Intent service) {
        //见补充1
        warnIfCallingFromSystemProcess();
        //见2.3,参数为true
        return startServiceCommon(service, true, mUser);
    }

>1.warnIfCallingFromSystemProcess

就是个警告,系统进程调用会有个警告日志。就是说系统进程调用必须后边加个AsUser并传递user参数。

startServiceAsUser
startForegroundServiceAsUser

2.3.startServiceCommon

  • requireForeground决定了是否是前台服务
    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
        try {
            //验证intent是否有效,就是必须有包名或者组件名
            validateServiceIntent(service);
            //见3.1,intent的准备工作处理
            service.prepareToLeaveProcess(this);
            //见4.1 ,这里的getService返回的就是AMS
            ComponentName cn = ActivityManager.getService().startService(
                    mMainThread.getApplicationThread(), service,
                    service.resolveTypeIfNeeded(getContentResolver()), requireForeground,
                    getOpPackageName(), getAttributionTag(), user.getIdentifier());
            if (cn != null) {
             //几种异常包名检查,抛出异常
                }
            }
            //返回的组件不为空,并且请求的是前台服务
            if (cn != null && requireForeground) {
                //服务组件的包名和当前上下文的包名一样
                if (cn.getPackageName().equals(getOpPackageName())) {
                //见小节6.1,添加一个异常对象到map里,到时候有异常的话再取出来使用
                //见6.4,启动前台通知以后,这个异常就被清除了
                    Service.setStartForegroundServiceStackTrace(cn.getClassName(),
                            new StackTrace("Last startServiceCommon() call for this service was "
                                    + "made here"));
                }
            }
            return cn;
        } 
    }

>1.getOpPackageName

正常就是当前上下文的包名,构造方法里创建对象的时候赋予的

    public String getOpPackageName() {
        return mAttributionSource.getPackageName();
    }

3.Intent.java

3.1.prepareToLeaveProcess

就是对比下当前上下文和intent里的包名是否一样,不一样就说明不是一个进程

    public void prepareToLeaveProcess(Context context) {
        final boolean leavingPackage;
        if (mComponent != null) {
        //当前上下文的包名和要跳转的服务包名不一样,则返回true,一样返回false
            leavingPackage = !Objects.equals(mComponent.getPackageName(), context.getPackageName());
        } else if (mPackage != null) {
            //包名不一样,则不是一个进程
            leavingPackage = !Objects.equals(mPackage, context.getPackageName());
        } else {
            //没有声明组件的,则认为还在当进程
            leavingPackage = true;
        }
        //见3.2
        prepareToLeaveProcess(leavingPackage);
    }

3.2.prepareToLeaveProcess

    public void prepareToLeaveProcess(boolean leavingPackage) {
    //见补充1,不允许fds
        setAllowFds(false);

        if (mSelector != null) {
            mSelector.prepareToLeaveProcess(leavingPackage);
        }
        if (mClipData != null) {
            mClipData.prepareToLeaveProcess(leavingPackage, getFlags());
        }
        if (mOriginalIntent != null) {
            mOriginalIntent.prepareToLeaveProcess(leavingPackage);
        }

        if (mExtras != null && !mExtras.isParcelled()) {
            final Object intent = mExtras.get(Intent.EXTRA_INTENT);
            if (intent instanceof Intent) {
                ((Intent) intent).prepareToLeaveProcess(leavingPackage);
            }
        }

        //..
    }

>1.setAllowFds

这篇讲了为啥intent无法传递大数据

  • allowFds 为true表示允许使用文件描述符,这样可以传递大数据,否则数据大小有限制,具体参考上边的帖子
public void setAllowFds(boolean allowFds) {
    if (mExtras != null) {
        mExtras.setAllowFds(allowFds);
    }
}

4.ActivityManagerService.java

4.1.startService

    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage,
            String callingFeatureId, int userId)
            throws TransactionTooLargeException {
        //具体见补充1,就是对caller的uid进行判定
        enforceNotIsolatedCaller("startService");
        //caller的uid在20000到29999,需要有对应的权限
        enforceAllowedToStartOrBindServiceIfSdkSandbox(service);
        if (service != null && service.hasFileDescriptors() == true) {
            //不允许有文件描述符
            throw new IllegalArgumentException("File descriptors passed in Intent");
        }

        synchronized(this) {
            ComponentName res;
            try {
            //见5.1
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, callingFeatureId, userId);
            return res;
        }
    }

>1.isIsolated

99000<=uid<=99999 或者90000<=uid<=98999

    public static final boolean isIsolated(int uid) {
        uid = UserHandle.getAppId(uid);
        return (uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID)
                || (uid >= FIRST_APP_ZYGOTE_ISOLATED_UID && uid <= LAST_APP_ZYGOTE_ISOLATED_UID);
    }

4.2.validateAssociationAllowedLocked

  • 运行在uid1下的pkg1 是否可以与 运行在uid2下的pkg2 进行交流?association
    boolean validateAssociationAllowedLocked(String pkg1, int uid1, String pkg2, int uid2) {
        // mAllowedAssociations集合数据读取
        ensureAllowedAssociations();
        if (uid1 == uid2 || UserHandle.getAppId(uid1) == SYSTEM_UID
                || UserHandle.getAppId(uid2) == SYSTEM_UID) {
        //uid一样,或者有一个是系统uid
            return true;
        }
        
        // Check for association on both source and target packages.
        //读取pkg1的关联信息,看pkg2是否在允许的关联里
        PackageAssociationInfo pai = mAllowedAssociations.get(pkg1);
        if (pai != null && !pai.isPackageAssociationAllowed(pkg2)) {
            return false;
        }
        //读取pkg2的关联信息,看pkg1是否在允许的关联里
        pai = mAllowedAssociations.get(pkg2);
        if (pai != null && !pai.isPackageAssociationAllowed(pkg1)) {
            return false;
        }
        //默认返回true,比如默认配置如果为空的话
        return true;
    }

4.3.crashApplicationWithTypeWithExtras

小节5.5调用

    public void crashApplicationWithTypeWithExtras(int uid, int initialPid, String packageName,
            int userId, String message, boolean force, int exceptionTypeId,
            @Nullable Bundle extras) {
        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                != PackageManager.PERMISSION_GRANTED) {
            //权限检查失败
            throw new SecurityException(msg);
        }

        synchronized(this) {
        //见9.1,使应用崩溃
            mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId,
                    message, force, exceptionTypeId, extras);
        }
    }

4.4.MainHandler

    final class MainHandler extends Handler {

>1.SERVICE_FOREGROUND_CRASH_MSG

            case SERVICE_FOREGROUND_CRASH_MSG: {
                SomeArgs args = (SomeArgs) msg.obj;
                //见5.5
                mServices.serviceForegroundCrash(
                        (ProcessRecord) args.arg1,
                        (String) args.arg2,
                        (ComponentName) args.arg3);
                args.recycle();
            } break;

>2.SERVICE_FOREGROUND_TIMEOUT_MSG

            case SERVICE_FOREGROUND_TIMEOUT_MSG: {
            //5.8处理
                mServices.serviceForegroundTimeout((ServiceRecord) msg.obj);
            } break;

>3.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG

            case SERVICE_FOREGROUND_TIMEOUT_ANR_MSG: {
                SomeArgs args = (SomeArgs) msg.obj;
                //5.12,启动超时ANR
                mServices.serviceForegroundTimeoutANR((ProcessRecord) args.arg1,
                        (String) args.arg2);
                args.recycle();
            } break;

5.ActiveServices.java

5.1.startServiceLocked

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String 
    //.. 增加最后两个参数
        return startServiceLocked(caller, service, resolvedType, callingPid, callingUid, fgRequired,
                callingPackage, callingFeatureId, userId, false, null);
    }

    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
            int callingPid, int callingUid, boolean fgRequired,
            String callingPackage, @Nullable String callingFeatureId, final int userId,
            boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
            throws TransactionTooLargeException {

        final boolean callerFg;
        if (caller != null) {
        //获取caller的进程信息
            final ProcessRecord callerApp = mAm.getRecordForAppLOSP(caller);
            if (callerApp == null) {
            //caller信息为空,抛出异常
                throw new SecurityException(//..
            }
            //非后台进程,那么就是前台
            callerFg = callerApp.mState.getSetSchedGroup() != ProcessList.SCHED_GROUP_BACKGROUND;
        } else {
            //为空,那么调用者是前台的
            callerFg = true;
        }
        //见5.2,检索要启动的服务
        ServiceLookupResult res =
            retrieveServiceLocked(service, null, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        if (res == null) {
            return null;
        }
        if (res.record == null) {
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }

        ServiceRecord r = res.record;
        //见补充1
        setFgsRestrictionLocked(callingPackage, callingPid, callingUid, service, r, userId,
                allowBackgroundActivityStarts);

        if (!mAm.mUserController.exists(r.userId)) {
            //user不存在
            return null;
        }

        //
        final boolean bgLaunch = !mAm.isUidActiveLOSP(r.appInfo.uid);

        //
        boolean forcedStandby = false;
        if (bgLaunch && appRestrictedAnyInBackground(r.appInfo.uid, r.packageName)) {
        //后台限制,改为标准的
            forcedStandby = true;
        }

        if (fgRequired) {
            
            if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
                //不允许启动前台服务,弹个通知
                showFgsBgRestrictedNotificationLocked(r);

                if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) {
                    throw new ForegroundServiceStartNotAllowedException(msg);
                }
                return null;
            }
        }

        // If this is a direct-to-foreground start, make sure it is allowed as per the app op.
        boolean forceSilentAbort = false;
        if (fgRequired) {
        //检查op是否允许启动前台服务
            final int mode = mAm.getAppOpsManager().checkOpNoThrow(
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
            switch (mode) {
                case AppOpsManager.MODE_ALLOWED:
                case AppOpsManager.MODE_DEFAULT:
                    // All okay.
                    break;
                case AppOpsManager.MODE_IGNORED:
                    //不允许
                    fgRequired = false;//改为非前台服务
                    forceSilentAbort = true;
                    break;
                default:
                    return new ComponentName("!!", "foreground not allowed as per app op");
            }
        }

        // If this isn't a direct-to-foreground start, check our ability to kick off an
        // arbitrary service
        if (forcedStandby || (!r.startRequested && !fgRequired)) {
            // 检查应用启动模式
            final int allowed = mAm.getAppStartModeLOSP(r.appInfo.uid, r.packageName,
                    r.appInfo.targetSdkVersion, callingPid, false, false, forcedStandby);
            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                //不允许
                if (allowed == ActivityManager.APP_START_MODE_DELAYED || forceSilentAbort) {

                    return null;
                }
                if (forcedStandby) {
                    if (fgRequired) {
                        return null;
                    }
                }

                UidRecord uidRec = mAm.mProcessList.getUidRecordLOSP(r.appInfo.uid);
                return new ComponentName("?", "app is in background uid " + uidRec);
            }
        }

        //8.0以下的
        if (r.appInfo.targetSdkVersion < Build.VERSION_CODES.O && fgRequired) {
            fgRequired = false;
        }

        //如果包是冻结状态,等待解冻,就是加入pending集合里,后续处理
        if (deferServiceBringupIfFrozenLocked(r, service, callingPackage, callingFeatureId,
                callingUid, callingPid, fgRequired, callerFg, userId, allowBackgroundActivityStarts,
                backgroundActivityStartsToken, false, null)) {
            return null;
        }

        // 检查启动目标是否需要权限
        if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage, callingFeatureId,
                callingUid, service, callerFg, userId, false, null)) {
            return null;
        }

        //见5.4,启动服务,返回组件
        final ComponentName realResult =
                startServiceInnerLocked(r, service, callingUid, callingPid, fgRequired, callerFg,
                allowBackgroundActivityStarts, backgroundActivityStartsToken);
        //有别名的,返回别名,否则返回真实的组件名
        if (res.aliasComponent != null
                && !realResult.getPackageName().startsWith("!")
                && !realResult.getPackageName().startsWith("?")) {
            return res.aliasComponent;
        } else {
            return realResult;
        }
    }

>1.setFgsRestrictionLocked

设置是否允许启动前台服务

  • mFlagBackgroundFgsStartRestrictionEnabled,常量true,表明后台启动前台服务的显示是否打开。打开的话,那么从后台启动的前台服务将没有while-in-using权限(比如定位,拍照等)。
    private void setFgsRestrictionLocked(String callingPackage,
            int callingPid, int callingUid, Intent intent, ServiceRecord r, int userId,
            boolean allowBackgroundActivityStarts) {
        r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime();
        // Check DeviceConfig flag.
        if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
            r.mAllowWhileInUsePermissionInFgs = true;
        }

        if (!r.mAllowWhileInUsePermissionInFgs
                || (r.mAllowStartForeground == REASON_DENIED)) {
            final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
                    callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts);
            if (!r.mAllowWhileInUsePermissionInFgs) {
                r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
            }
            if (r.mAllowStartForeground == REASON_DENIED) {
                r.mAllowStartForeground = shouldAllowFgsStartForegroundWithBindingCheckLocked(
                        allowWhileInUse, callingPackage, callingPid, callingUid, intent, r,
                        userId);
            }
        }
    }

5.2.retrieveServiceLocked

    private ServiceLookupResult retrieveServiceLocked(Intent service,
            String instanceName, boolean isSdkSandboxService, int sdkSandboxClientAppUid,
            String sdkSandboxClientAppPackage, String resolvedType,
            String callingPackage, int callingPid, int callingUid, int userId,
            boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal,//false
            boolean allowInstant) {//false

        ServiceRecord r = null;

        userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId,
                /* allowAll= */false, getAllowMode(service, callingPackage),
                /* name= */ "service", callingPackage);
        //获取用户的服务map,见补充1
        ServiceMap smap = getServiceMapLocked(userId);

        //service可能提供的是个别名,这里是找到最终的目标组件
        final ComponentAliasResolver.Resolution<ComponentName> resolution =
                mAm.mComponentAliasResolver.resolveService(service, resolvedType,
                        /* match flags */ 0, userId, callingUid);

        final ComponentName comp;
        if (instanceName == null) {
            //参考5.1,会走这里
            comp = service.getComponent();
        } else {
            final ComponentName realComp = service.getComponent();
            if (realComp == null) {
                throw new IllegalArgumentException("Can't use custom instance name '" + instanceName
                        + "' without expicit component in Intent");
            }
            comp = new ComponentName(realComp.getPackageName(),
                    realComp.getClassName() + ":" + instanceName);
        }

        if (comp != null) {
        //先通过组件名查找已有的serviceRecord,见5.3
            r = smap.mServicesByInstanceName.get(comp);

        }
        if (r == null && !isBindExternal && instanceName == null) {
            //没找到r,那么通过IntentFilter查找
            Intent.FilterComparison filter = new Intent.FilterComparison(service);
            //见5.3
            r = smap.mServicesByIntent.get(filter);
        }
        if (r != null) {
            //是否过滤对应用程序的访问,一般instant应用需要过滤
            if (mAm.getPackageManagerInternal().filterAppAccess(r.packageName, callingUid,
                    userId)) {
            //是的话返回空。
                return null;
            }
            //外部服务,服务包名和调用者包名不一样,换句话说,外部服务在自己的包进程里运行
            if ((r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
                    && !callingPackage.equals(r.packageName)) {
                //置空
                r = null;
            }
        }
        if (r == null) {
            try {
                int flags = ActivityManagerService.STOCK_PM_FLAGS
                        | PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
                if (allowInstant) {
                    flags |= PackageManager.MATCH_INSTANT;
                }
                //读取服务info
                ResolveInfo rInfo = mAm.getPackageManagerInternal().resolveService(service,
                        resolvedType, flags, userId, callingUid);
                ServiceInfo sInfo = rInfo != null ? rInfo.serviceInfo : null;
                if (sInfo == null) {
                    //没找到对应的服务
                    return null;
                }
            //..

                ComponentName className = new ComponentName(sInfo.applicationInfo.packageName,
                                                            sInfo.name);
                ComponentName name = comp != null ? comp : className;
                //见4.2,验证callingPkg是否可以启动service包
                if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid,
                        name.getPackageName(), sInfo.applicationInfo.uid)) {
                    String msg = "association not allowed between packages "
                            + callingPackage + " and " + name.getPackageName();
                    //失败
                    return new ServiceLookupResult(msg);
                }

                //
                String definingPackageName = sInfo.applicationInfo.packageName;
                int definingUid = sInfo.applicationInfo.uid;
                //服务里有外部服务的标志
                if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
                    //有BIND_EXTERNAL_SERVICE标志
                    if (isBindExternal) {
                        if (!sInfo.exported) {
                        //exported属性必须为true
                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
                                    + className + " is not exported");
                        }
                        if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
                        //isolated属性也必须为true,见补充2
                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, "
                                    + className + " is not an isolatedProcess");
                        }
                        //在caller包下运行服务
                        ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
                                callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
                        if (aInfo == null) {
                            throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " +
                                    "could not resolve client package " + callingPackage);
                        }
                        sInfo = new ServiceInfo(sInfo);
                        sInfo.applicationInfo = new ApplicationInfo(sInfo.applicationInfo);
                        sInfo.applicationInfo.packageName = aInfo.packageName;
                        sInfo.applicationInfo.uid = aInfo.uid;
                        name = new ComponentName(aInfo.packageName, name.getClassName());
                        className = new ComponentName(aInfo.packageName,
                                instanceName == null ? className.getClassName()
                                        : (className.getClassName() + ":" + instanceName));
                        service.setComponent(name);
                    } else {
                    //缺少 BIND_EXTERNAL_SERVICE标志
                        throw new SecurityException("BIND_EXTERNAL_SERVICE required for " +
                                name);
                    }
                } else if (isBindExternal) {
                    throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
                            " is not an externalService");
                }
                if (userId > 0) {//非系统用户
                    //单例模式
                    if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
                            sInfo.name, sInfo.flags)
                            && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
                        userId = 0;
                        smap = getServiceMapLocked(0);
                        try {
                            ResolveInfo rInfoForUserId0 =
                                    mAm.getPackageManagerInternal().resolveService(service,
                                            resolvedType, flags, userId, callingUid);
                            if (rInfoForUserId0 == null) {
                                return null;
                            }
                            sInfo = rInfoForUserId0.serviceInfo;
                        }
                    }
                    sInfo = new ServiceInfo(sInfo);
                    sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
                }
                r = smap.mServicesByInstanceName.get(name);
                
                if (r == null && createIfNeeded) {
                    //没有找到旧的服务,创建新的
                    final Intent.FilterComparison filter
                            = new Intent.FilterComparison(service.cloneFilter());
                    //服务重启Runnable对象
                    final ServiceRestarter res = new ServiceRestarter();
                    String sdkSandboxProcessName = isSdkSandboxService ? instanceName : null;
                    //实例化新的对象
                    r = new ServiceRecord(mAm, className, name, definingPackageName,
                            definingUid, filter, sInfo, callingFromFg, res,
                            sdkSandboxProcessName, sdkSandboxClientAppUid,
                            sdkSandboxClientAppPackage);
                    res.setService(r);
                    //放入集合
                    smap.mServicesByInstanceName.put(name, r);
                    smap.mServicesByIntent.put(filter, r);

                    for (int i=mPendingServices.size()-1; i>=0; i--) {
                        final ServiceRecord pr = mPendingServices.get(i);
                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                                && pr.instanceName.equals(name)) {
                            //从等待的intent里移除,就是要启动的服务,等待服务的应用启动中
                            mPendingServices.remove(i);
                        }
                    }
                    for (int i = mPendingBringups.size() - 1; i >= 0; i--) {
                        final ServiceRecord pr = mPendingBringups.keyAt(i);
                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
                                && pr.instanceName.equals(name)) {
                        //start或者bind的服务,还没ready的集合里移除
                            mPendingBringups.removeAt(i);
                        }
                    }

                }
            }
        }
        if (r != null) {
            r.mRecentCallingPackage = callingPackage;
            r.mRecentCallingUid = callingUid;
            try {
                //存储最后调用者的应用信息
                r.mRecentCallerApplicationInfo =
                        mAm.mContext.getPackageManager().getApplicationInfoAsUser(callingPackage,
                                0, UserHandle.getUserId(callingUid));
            } catch (PackageManager.NameNotFoundException e) {
            }
            //见4.2,咋又验证一次。。
            if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName,
                    r.appInfo.uid)) {
                String msg = "association not allowed between packages "
                        + callingPackage + " and " + r.packageName;
                //失败
                return new ServiceLookupResult(msg);
            }
            //防火墙,就是一些配置,这里继续检查是否满足配置
            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
                    resolvedType, r.appInfo)) {
                //失败
                return new ServiceLookupResult("blocked by firewall");
            }
            //检查服务里声明需要的权限,
            if (mAm.checkComponentPermission(r.permission,
                    callingPid, callingUid, r.appInfo.uid, r.exported) != PERMISSION_GRANTED) {
                //权限检查失败
                if (!r.exported) {
                    return new ServiceLookupResult("not exported from uid "
                            + r.appInfo.uid);
                }
                return new ServiceLookupResult(r.permission);
            } else if (Manifest.permission.BIND_HOTWORD_DETECTION_SERVICE.equals(r.permission)
                    && callingUid != Process.SYSTEM_UID) {
                //特殊权限,只能是系统才能启动
                return new ServiceLookupResult("can only be bound to "
                        + "by the system.");
            } else if (r.permission != null && callingPackage != null) {
            //权限转化为opCode,再次检查
                final int opCode = AppOpsManager.permissionToOpCode(r.permission);
                if (opCode != AppOpsManager.OP_NONE && mAm.getAppOpsManager().checkOpNoThrow(
                        opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
                //失败
                    return null;
                }
            }
            //成功
            return new ServiceLookupResult(r, resolution.getAlias());
        }
        return null;
    }

>1.getServiceMapLocked

获取对应用户的服务map

    private ServiceMap getServiceMapLocked(int callingUser) {
        ServiceMap smap = mServiceMap.get(callingUser);
        if (smap == null) {
            //没有的话创建新的,加入map
            smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
            mServiceMap.put(callingUser, smap);
        }
        return smap;
    }

>2.FLAG_EXTERNAL_SERVICE

externalService标签,也就是FLAG_EXTERNAL_SERVICE的作用

  • exported ,externalService ,isolatedProcess 3个属性都必须设置为true
  • bindService必须加对应的flag:BIND_EXTERNAL_SERVICE
  • 就是说谁启动的这个服务,这个服务就在谁的进程下运行。
bindService(intent, mConnection, Context.BIND_AUTO_CREATE | Context.BIND_EXTERNAL_SERVICE);

<service
    android:name=".MyTestService"
    android:externalService="true"
    android:isolatedProcess="true"
    android:exported="true">

5.3.ServiceMap

Information about services for a single user.

    final class ServiceMap extends Handler {
        final int mUserId;
        //组件名映射服务记录
        final ArrayMap<ComponentName, ServiceRecord> mServicesByInstanceName = new ArrayMap<>();
        final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = new ArrayMap<>();

        final ArrayList<ServiceRecord> mDelayedStartList = new ArrayList<>();

5.4.startServiceInnerLocked

    private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
            int callingUid, int callingPid, boolean fgRequired, boolean callerFg,
            boolean allowBackgroundActivityStarts, @Nullable IBinder backgroundActivityStartsToken)
            throws TransactionTooLargeException {
        NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
                service, callingUid, r.packageName, r.userId);
        //如果在重启中的服务集合里,那么移除
        if (unscheduleServiceRestartLocked(r, callingUid, false)) {
        }
        final boolean wasStartRequested = r.startRequested;
        r.lastActivity = SystemClock.uptimeMillis();
        r.startRequested = true;//有人明确的调用了start方法启动的。
        r.delayedStop = false;
        r.fgRequired = fgRequired;
        //意图启动集合里添加数据
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                service, neededGrants, callingUid));

        if (fgRequired) {
            // We are now effectively running a foreground service.
            synchronized (mAm.mProcessStats.mLock) {
                final ServiceState stracker = r.getTracker();
                if (stracker != null) {
                //设置前台服务状态
                    stracker.setForeground(true, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis()); // Use current time, not lastActivity.
                }
            }
            mAm.mAppOpsService.startOperation(AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null,
                    true, false, null, false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
                    AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
        }

        final ServiceMap smap = getServiceMapLocked(r.userId);
        boolean addToStarting = false;
        //caller是后台的,启动的也不是前台服务,服务的进程记录为空
        if (!callerFg && !fgRequired && r.app == null
                && mAm.mUserController.hasStartedUserState(r.userId)) {//用户已启动
            //根据进程名和uid查找进程记录信息
            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid);
            //没找到或者状态大于1010
            if (proc == null || proc.mState.getCurProcState() > PROCESS_STATE_RECEIVER) {
                if (r.delayed) {//后台等待启动服务为true
                    return r.name;
                }
                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
                    //后台启动的服务数超标了,加入delay集合里
                    smap.mDelayedStartList.add(r);
                    r.delayed = true;
                    return r.name;
                }
                
                addToStarting = true;
            } else if (proc.mState.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) //1009{
                addToStarting = true;
            }
            
        if (allowBackgroundActivityStarts) {//false
            r.allowBgActivityStartsOnServiceStart(backgroundActivityStartsToken);
        }
        //见补充1
        ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
                callingUid, wasStartRequested);
        return cmp;
    }

>1.startServiceInnerLocked

    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting, int callingUid, boolean wasStartRequested)
            throws TransactionTooLargeException {
        synchronized (mAm.mProcessStats.mLock) {
            final ServiceState stracker = r.getTracker();
            if (stracker != null) {
            //设置启动状态为true
                stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(),
                        SystemClock.uptimeMillis()); // Use current time, not lastActivity.
            }
        }
        r.callStart = false;

        final int uid = r.appInfo.uid;
        final String packageName = r.name.getPackageName();
        final String serviceName = r.name.getClassName();

        mAm.mBatteryStatsService.noteServiceStartRunning(uid, packageName, serviceName);
        //见补充2,拉起服务
        String error = bringUpServiceLocked(r, service.getFlags(), callerFg,
                false /* whileRestarting */,
                false /* permissionsReviewRequired */,
                false /* packageFrozen */,
                true /* enqueueOomAdj */);
        
        mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        if (error != null) {
            return new ComponentName("!!", error);
        }

        if (r.startRequested && addToStarting) {
            boolean first = smap.mStartingBackground.size() == 0;
            smap.mStartingBackground.add(r);
            r.startingBgTimeout = SystemClock.uptimeMillis() + mAm.mConstants.BG_START_TIMEOUT;

            if (first) {
                smap.rescheduleDelayedStartsLocked();
            }
        } else if (callerFg || r.fgRequired) {
            //从后台启动服务集合里移除,从延迟启动服务里移除
            smap.ensureNotStartingBackgroundLocked(r);
        }

        return r.name;
    }

>2.bringUpServiceLocked

  • 如果服务已经启动,会走5.4.4更新服务状态,最终走7.3.1,以及7.4,最后回到5.10。
  • 如果服务还未启动,并且isolated为false(一般都是false,除非你手动声明为true),判断服务对应的应用是否已启动,启动话,那么启动对应的服务,见5.11以及7.3.2和7.5
  • 继续判断如果应用未启动,那么启动应用,并把ServiceRecord加入mPendingServices等待应用启动成功再启动服务。
    private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
            boolean whileRestarting, boolean permissionsReviewRequired, boolean packageFrozen,
            boolean enqueueOomAdj){
        //服务进程信息不为空,应用线程也不为空
        if (r.app != null && r.app.getThread() != null) {
            //见补充4,更新服务
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }

        if (!whileRestarting && mRestartingServices.contains(r)) {
            // 等待重启中
            return null;
        }

        //从集合移除
        if (mRestartingServices.remove(r)) {
            clearRestartingIfNeededLocked(r);
        }

        //如果在延迟启动集合里,移除,因为我们现在要启动它了。
        if (r.delayed) {
            getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (!mAm.mUserController.hasStartedUserState(r.userId)) {
            //服务对应的user还没启动,干掉服务,见补充3
            bringDownServiceLocked(r, enqueueOomAdj);
            return msg;
        }

        // Report usage if binding is from a different package except for explicitly exempted
        // bindings
        if (!r.appInfo.packageName.equals(r.mRecentCallingPackage)
                && !r.isNotAppComponentUsage) {
            mAm.mUsageStatsService.reportEvent(
                    r.packageName, r.userId, UsageEvents.Event.APP_COMPONENT_USED);
        }

        //服务要启动了,它的包不能是stop状态
        try {
            AppGlobals.getPackageManager().setPackageStoppedState(
                    r.packageName, false, r.userId);
        } 

        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
        final String procName = r.processName;
        HostingRecord hostingRecord = new HostingRecord(
                HostingRecord.HOSTING_TYPE_SERVICE, r.instanceName,
                r.definingPackageName, r.definingUid, r.serviceInfo.processName,
                getHostingRecordTriggerType(r));
        ProcessRecord app;

        if (!isolated) {//非隔离的服务,
            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid);
            if (app != null) {//应用进程不为空
                final IApplicationThread thread = app.getThread();
                final int pid = app.getPid();
                final UidRecord uidRecord = app.getUidRecord();
                if (thread != null) {//主线程不为空
                    try {//加入集合
                        app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode,
                                mAm.mProcessStats);
                        //启动服务,见5.11
                        realStartServiceLocked(r, app, thread, pid, uidRecord, execInFg,
                                enqueueOomAdj);
                        return null;
                    } 
                }
            }
        } else {//运行在隔离的进程里,
            app = r.isolationHostProc;
            if (WebViewZygote.isMultiprocessEnabled()
                    && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
                hostingRecord = HostingRecord.byWebviewZygote(r.instanceName, r.definingPackageName,
                        r.definingUid, r.serviceInfo.processName);
            }
            if ((r.serviceInfo.flags & ServiceInfo.FLAG_USE_APP_ZYGOTE) != 0) {
                hostingRecord = HostingRecord.byAppZygote(r.instanceName, r.definingPackageName,
                        r.definingUid, r.serviceInfo.processName);
            }
        }

        // 没有启动
        if (app == null && !permissionsReviewRequired && !packageFrozen) {
            if (r.isSdkSandbox) {
                final int uid = Process.toSdkSandboxUid(r.sdkSandboxClientAppUid);
                app = mAm.startSdkSandboxProcessLocked(procName, r.appInfo, true, intentFlags,
                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, uid, r.sdkSandboxClientAppPackage);
                r.isolationHostProc = app;
            } else {
            //启动应用进程
                app = mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                        hostingRecord, ZYGOTE_POLICY_FLAG_EMPTY, false, isolated);
            }
            if (app == null) {
                //应用无法启动,停止服务,见补充3
                bringDownServiceLocked(r, enqueueOomAdj);
                return msg;
            }
            if (isolated) {
                r.isolationHostProc = app;
            }
        }

        if (r.fgRequired) {
        //要启动前台服务,临时绕过省电模式
            mAm.tempAllowlistUidLocked(r.appInfo.uid,
                    mAm.mConstants.mServiceStartForegroundTimeoutMs, REASON_SERVICE_LAUNCH,
                    "fg-service-launch",
                    TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                    r.mRecentCallingUid);
        }
        //加入pending,上边应用启动以后,会查找这个集合再启动对应的服务
        if (!mPendingServices.contains(r)) {
            mPendingServices.add(r);
        }

        if (r.delayedStop) {
            // 延迟停止状态
            r.delayedStop = false;
            if (r.startRequested) {//又需要启动
                stopServiceLocked(r, enqueueOomAdj);
            }
        }

        return null;
    }

>3.bringDownServiceLocked

这个方法被调用的地方有点多,有差不多10处了。

    private void bringDownServiceLocked(ServiceRecord r, boolean enqueueOomAdj) {

        ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections = r.getConnections();
        for (int conni = connections.size() - 1; conni >= 0; conni--) {
            ArrayList<ConnectionRecord> c = connections.valueAt(conni);
            for (int i=0; i<c.size(); i++) {
                ConnectionRecord cr = c.get(i);
                // 报告所有的连接,服务不可用
                cr.serviceDead = true;
                cr.stopAssociation();
                final ComponentName clientSideComponentName =
                        cr.aliasComponent != null ? cr.aliasComponent : r.name;
                try {//就是调用ServiceConnection的onBindingDied方法
                    cr.conn.connected(r.name, null, true);//true表示dead
                }
            }
        }

        boolean oomAdjusted = false;
        // 告诉服务它已解除绑定
        if (r.app != null && r.app.getThread() != null) {
            for (int i = r.bindings.size() - 1; i >= 0; i--) {
                IntentBindRecord ibr = r.bindings.valueAt(i);
                if (ibr.hasBound) {
                    try {
                        oomAdjusted |= bumpServiceExecutingLocked(r, false, "bring down unbind",
                                OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                        ibr.hasBound = false;
                        ibr.requested = false;
                        r.app.getThread().scheduleUnbindService(r,
                                ibr.intent.getIntent());
                    } 
                }
            }
        }

        if (r.fgRequired) {
            r.fgRequired = false;
            r.fgWaiting = false;
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                //设置前台服务为false
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            //结束启动前台服务的操作
            mAm.mAppOpsService.finishOperation(AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
            mAm.mHandler.removeMessages(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            if (r.app != null) {
            //发送crash的消息,见4.4.1
                Message msg = mAm.mHandler.obtainMessage(
                        ActivityManagerService.SERVICE_FOREGROUND_CRASH_MSG);
                SomeArgs args = SomeArgs.obtain();
                args.arg1 = r.app;
                args.arg2 = r.toString();
                args.arg3 = r.getComponentName();

                msg.obj = args;
                mAm.mHandler.sendMessage(msg);
            }
        }


        r.destroyTime = SystemClock.uptimeMillis();

        final ServiceMap smap = getServiceMapLocked(r.userId);
        ServiceRecord found = smap.mServicesByInstanceName.remove(r.instanceName);

        // Note when this method is called by bringUpServiceLocked(), the service is not found
        // in mServicesByInstanceName and found will be null.
        if (found != null && found != r) {
            // This is not actually the service we think is running...  this should not happen,
            // but if it does, fail hard.
            smap.mServicesByInstanceName.put(r.instanceName, found);
            throw new IllegalStateException("Bringing down " + r + " but actually running "
                    + found);
        }
        smap.mServicesByIntent.remove(r.intent);
        r.totalRestartCount = 0;
        unscheduleServiceRestartLocked(r, 0, true);

        // Also make sure it is not on the pending list.
        for (int i=mPendingServices.size()-1; i>=0; i--) {
            if (mPendingServices.get(i) == r) {
                mPendingServices.remove(i);
              
            }
        }

        cancelForegroundNotificationLocked(r);
        final boolean exitingFg = r.isForeground;
        if (exitingFg) {
            decActiveForegroundAppLocked(smap, r);
            synchronized (mAm.mProcessStats.mLock) {
                ServiceState stracker = r.getTracker();
                if (stracker != null) {
                    stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                            SystemClock.uptimeMillis());
                }
            }
            mAm.mAppOpsService.finishOperation(
                    AppOpsManager.getToken(mAm.mAppOpsService),
                    AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
            unregisterAppOpCallbackLocked(r);
            r.mFgsExitTime = SystemClock.uptimeMillis();

            mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
        }

        r.isForeground = false;
        r.mFgsNotificationWasDeferred = false;
        dropFgsNotificationStateLocked(r);
        r.foregroundId = 0;
        r.foregroundNoti = null;
        resetFgsRestrictionLocked(r);
        if (exitingFg) {
            signalForegroundServiceObserversLocked(r);
        }

        // Clear start entries.
        r.clearDeliveredStartsLocked();
        r.pendingStarts.clear();
        smap.mDelayedStartList.remove(r);

        if (r.app != null) {
            mAm.mBatteryStatsService.noteServiceStopLaunch(r.appInfo.uid, r.name.getPackageName(),
                    r.name.getClassName());
            stopServiceAndUpdateAllowlistManagerLocked(r);
            if (r.app.getThread() != null) {
                // Bump the process to the top of LRU list
                mAm.updateLruProcessLocked(r.app, false, null);
                updateServiceForegroundLocked(r.app.mServices, false);
                try {
                    oomAdjusted |= bumpServiceExecutingLocked(r, false, "destroy",
                            oomAdjusted ? null : OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                    mDestroyingServices.add(r);
                    r.destroying = true;
                    r.app.getThread().scheduleStopService(r);
                } catch (Exception e) {
                    Slog.w(TAG, "Exception when destroying service "
                            + r.shortInstanceName, e);
                    serviceProcessGoneLocked(r, enqueueOomAdj);
                }
            } 
        }

        if (!oomAdjusted) {
            mAm.enqueueOomAdjTargetLocked(r.app);
            if (!enqueueOomAdj) {
                mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
            }
        }
        if (r.bindings.size() > 0) {
            r.bindings.clear();
        }

        if (r.restarter instanceof ServiceRestarter) {
           ((ServiceRestarter)r.restarter).setService(null);
        }

        synchronized (mAm.mProcessStats.mLock) {
            final int memFactor = mAm.mProcessStats.getMemFactorLocked();
            if (r.tracker != null) {
                final long now = SystemClock.uptimeMillis();
                r.tracker.setStarted(false, memFactor, now);
                r.tracker.setBound(false, memFactor, now);
                if (r.executeNesting == 0) {
                    r.tracker.clearCurrentOwner(r, false);
                    r.tracker = null;
                }
            }
        }

        smap.ensureNotStartingBackgroundLocked(r);
        updateNumForegroundServicesLocked();
    }

>4.sendServiceArgsLocked

走到这里说明有已经启动的服务

  • 这里添加了超时msg,具体见5.9
    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
        final int N = r.pendingStarts.size();
        if (N == 0) {
            return;
        }

        ArrayList<ServiceStartArgs> args = new ArrayList<>();

        while (r.pendingStarts.size() > 0) {
            ServiceRecord.StartItem si = r.pendingStarts.remove(0);

            if (si.intent == null && N > 1) {
                continue;
            }
            si.deliveredTime = SystemClock.uptimeMillis();
            //加入已投递集合
            r.deliveredStarts.add(si);
            si.deliveryCount++;
            if (si.neededGrants != null) {
            //服务如果有需要的权限的话,进行验证
                mAm.mUgmInternal.grantUriPermissionUncheckedFromIntent(si.neededGrants,
                        si.getUriPermissionsLocked());
            }
            mAm.grantImplicitAccess(r.userId, si.intent, si.callingId,
                    UserHandle.getAppId(r.appInfo.uid)
            );
            //服务进入执行状态
            bumpServiceExecutingLocked(r, execInFg, "start", null /* oomAdjReason */);
            //需要前台服务并且进入前台服务超时时间还未设置
            if (r.fgRequired && !r.fgWaiting) {
                if (!r.isForeground) {//还不是前台服务
                    //添加进入前台服务超时时间,见5.9
                    scheduleServiceForegroundTransitionTimeoutLocked(r);
                } else {//已经是前台服务了,那么需求的标志改为false
                    r.fgRequired = false;
                }
            }
            int flags = 0;
            if (si.deliveryCount > 1) {
                flags |= Service.START_FLAG_RETRY;
            }
            if (si.doneExecutingCount > 0) {
                flags |= Service.START_FLAG_REDELIVERY;
            }
            //加入集合
            args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
        }

        if (!oomAdjusted) {
            mAm.enqueueOomAdjTargetLocked(r.app);
            mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        }
        //args放入集合
        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
        slice.setInlineCountLimit(4);
        Exception caughtException = null;
        try {//见7.3.1
            r.app.getThread().scheduleServiceArgs(r, slice);
        }catch
        //..

    }

5.5.serviceForegroundCrash

使前台服务崩溃

    void serviceForegroundCrash(ProcessRecord app, String serviceRecord,
            ComponentName service) {
            //又回到4.3
        mAm.crashApplicationWithTypeWithExtras(
                app.uid, app.getPid(), app.info.packageName, app.userId,
                "Context.startForegroundService() did not then call " + "Service.startForeground(): "
                    + serviceRecord, false /*force*/,
                ForegroundServiceDidNotStartInTimeException.TYPE_ID,
                ForegroundServiceDidNotStartInTimeException.createExtrasForService(service));
    }

5.6.setServiceForegroundLocked

  • 小节6.4,id一般不为0,notification不为空,flags为0,foregroundServiceType不为0
  • 小节6.5,id为0,notification为空,flags为0,1,2,foregroundServiceType为0
    public void setServiceForegroundLocked(ComponentName className, IBinder token,
            int id, Notification notification, int flags, int foregroundServiceType) {
        try {
            //根据组件名找到已有的r
            ServiceRecord r = findServiceLocked(className, token, userId);
            if (r != null) {
                //见5.7,设置为前台服务状态
                setServiceForegroundInnerLocked(r, id, notification, flags, foregroundServiceType);
            }
        }
    }

5.7.setServiceForegroundInnerLocked

    private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
            Notification notification, int flags, int foregroundServiceType) {
        if (id != 0) {//正常是启动前台通知
            if (notification == null) {
                throw new IllegalArgumentException("null notification");
            }
            // Instant apps 需要权限创建前台服务
            if (r.appInfo.isInstantApp()) {
                final int mode = mAm.getAppOpsManager().checkOpNoThrow(
                        AppOpsManager.OP_INSTANT_APP_START_FOREGROUND,
                        r.appInfo.uid,
                        r.appInfo.packageName);
                switch (mode) {
                    case AppOpsManager.MODE_ALLOWED://权限已允许
                        break;
                    case AppOpsManager.MODE_IGNORED:
                        //无视,那么返回
                        return;
                    case AppOpsManager.MODE_ERRORED:
                        throw new SecurityException("Instant app " + r.appInfo.packageName
                                + " does not have permission to create foreground services");
                    default://检查权限
                        mAm.enforcePermission(
                                android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
                                r.app.getPid(), r.appInfo.uid, "startForeground");
                }
            } else {//正常的应用
                if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
                //检查权限
                    mAm.enforcePermission(
                            android.Manifest.permission.FOREGROUND_SERVICE,
                            r.app.getPid(), r.appInfo.uid, "startForeground");
                }

                int manifestType = r.serviceInfo.getForegroundServiceType();
                //
                if (foregroundServiceType == FOREGROUND_SERVICE_TYPE_MANIFEST) {
                    foregroundServiceType = manifestType;
                }
                //
                if ((foregroundServiceType & manifestType) != foregroundServiceType) {
                    throw new IllegalArgumentException("foregroundServiceType "
                    //..
                }
            }

            boolean alreadyStartedOp = false;
            boolean stopProcStatsOp = false;
            if (r.fgRequired) {

                r.fgRequired = false;
                r.fgWaiting = false;
                alreadyStartedOp = stopProcStatsOp = true;
                //移除前台服务超时msg,5.9里添加的
                mAm.mHandler.removeMessages(
                        ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            }

            final ProcessServiceRecord psr = r.app.mServices;
            try {
                boolean ignoreForeground = false;
                final int mode = mAm.getAppOpsManager().checkOpNoThrow(
                        AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName);
                switch (mode) {
                    case AppOpsManager.MODE_ALLOWED:
                    case AppOpsManager.MODE_DEFAULT:
                        // All okay.
                        break;
                    case AppOpsManager.MODE_IGNORED:
                        //启动前台服务的操作不允许
                        ignoreForeground = true;
                        break;
                    default:
                        throw new SecurityException("Foreground not allowed as per app op");
                }

                if (!ignoreForeground
                        && !isForegroundServiceAllowedInBackgroundRestricted(r.app)) {
                    updateServiceForegroundLocked(psr, false);
                    ignoreForeground = true;
                }

                if (!ignoreForeground) {
                    if (r.mStartForegroundCount == 0) {//已启动的前台服务数为0
                        if (!r.fgRequired) {//不需要前台服务
                            final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
                            if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
                                resetFgsRestrictionLocked(r);
                                setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
                                        r.appInfo.uid, r.intent.getIntent(), r, r.userId, false);
        //..
                            }
                        }
                    } else if (r.mStartForegroundCount >= 1) {
                        //
                        setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.getPid(),
                                r.appInfo.uid, r.intent.getIntent(), r, r.userId, false);
                    }
                    //不允许启动前台服务
                    if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) {
                        
                        showFgsBgRestrictedNotificationLocked(r);
                        updateServiceForegroundLocked(psr, true);
                        ignoreForeground = true;
                        if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID,
                                r.appInfo.uid)) {
                            throw new ForegroundServiceStartNotAllowedException(msg);
                        }
                    }
                }
                if (!ignoreForeground) {
                    if (r.foregroundId != id) {
                        cancelForegroundNotificationLocked(r);
                        r.foregroundId = id;
                    }
                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
                    r.foregroundNoti = notification;
                    r.foregroundServiceType = foregroundServiceType;
                    if (!r.isForeground) {
                        final ServiceMap smap = getServiceMapLocked(r.userId);
                        if (smap != null) {
                            ActiveForegroundApp active = smap.mActiveForegroundApps
                                    .get(r.packageName);
                            if (active == null) {
                                active = new ActiveForegroundApp();
                                active.mPackageName = r.packageName;
                                active.mUid = r.appInfo.uid;
                                active.mShownWhileScreenOn = mScreenOn;
                                if (r.app != null) {
                                    final UidRecord uidRec = r.app.getUidRecord();
                                    if (uidRec != null) {
                                        active.mAppOnTop = active.mShownWhileTop =
                                                uidRec.getCurProcState() <= PROCESS_STATE_TOP;
                                    }
                                }
                                active.mStartTime = active.mStartVisibleTime
                                        = SystemClock.elapsedRealtime();
                                smap.mActiveForegroundApps.put(r.packageName, active);
                                requestUpdateActiveForegroundAppsLocked(smap, 0);
                            }
                            active.mNumActive++;
                        }
                        //到这里才算已经是前台服务了。
                        r.isForeground = true;

                        r.mAllowStartForegroundAtEntering = r.mAllowStartForeground;
                        r.mAllowWhileInUsePermissionInFgsAtEntering =
                                r.mAllowWhileInUsePermissionInFgs;
                        r.mStartForegroundCount++;
                        r.mFgsEnterTime = SystemClock.uptimeMillis();
                        if (!stopProcStatsOp) {
                            synchronized (mAm.mProcessStats.mLock) {
                                final ServiceState stracker = r.getTracker();
                                if (stracker != null) {
                                    stracker.setForeground(true,
                                            mAm.mProcessStats.getMemFactorLocked(),
                                            SystemClock.uptimeMillis());
                                }
                            }
                        } else {
                            stopProcStatsOp = false;
                        }
                        //启动前台服务操作
                        mAm.mAppOpsService.startOperation(
                                AppOpsManager.getToken(mAm.mAppOpsService),
                                AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
                                null, true, false, "", false, AppOpsManager.ATTRIBUTION_FLAGS_NONE,
                                AppOpsManager.ATTRIBUTION_CHAIN_ID_NONE);
                        registerAppOpCallbackLocked(r);
                        mAm.updateForegroundServiceUsageStats(r.name, r.userId, true);

                        updateNumForegroundServicesLocked();
                    }

                    signalForegroundServiceObserversLocked(r);
                    //显示通知,见10.2
                    r.postNotification();
                    if (r.app != null) {
                        updateServiceForegroundLocked(psr, true);
                    }
                    getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r);
                    mAm.notifyPackageUse(r.serviceInfo.packageName,
                            PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
                } 
            } finally {
                if (stopProcStatsOp) {
                    synchronized (mAm.mProcessStats.mLock) {
                        final ServiceState stracker = r.getTracker();
                        if (stracker != null) {
                            stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                                    SystemClock.uptimeMillis());
                        }
                    }
                }
                if (alreadyStartedOp) {
                    mAm.mAppOpsService.finishOperation(
                            AppOpsManager.getToken(mAm.mAppOpsService),
                            AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName,
                            null);
                }
            }
        } else {//这里是通知id等于0的情况,一般是停止前台通知
            if (r.isForeground) {
                final ServiceMap smap = getServiceMapLocked(r.userId);
                if (smap != null) {
                    decActiveForegroundAppLocked(smap, r);
                }

                if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
                    //取消通知
                    cancelForegroundNotificationLocked(r);
                    r.foregroundId = 0;
                    r.foregroundNoti = null;
                } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
                    // if it's been deferred, force to visibility
                    if (!r.mFgsNotificationShown) {
                        r.postNotification();
                    }
                    //如果没有其他前台服务公用这个通知,那么移除所有相关的flag,否则啥也不做
                    dropFgsNotificationStateLocked(r);
                    if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
                        r.foregroundId = 0;
                        r.foregroundNoti = null;
                    }
                }

                r.isForeground = false;
                r.mFgsExitTime = SystemClock.uptimeMillis();
                synchronized (mAm.mProcessStats.mLock) {
                    final ServiceState stracker = r.getTracker();
                    if (stracker != null) {
                    //设置前台标志为false
                        stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
                                SystemClock.uptimeMillis());
                    }
                }
                mAm.mAppOpsService.finishOperation(
                        AppOpsManager.getToken(mAm.mAppOpsService),
                        AppOpsManager.OP_START_FOREGROUND, r.appInfo.uid, r.packageName, null);
                unregisterAppOpCallbackLocked(r);

                r.mFgsNotificationWasDeferred = false;
                signalForegroundServiceObserversLocked(r);
                resetFgsRestrictionLocked(r);
                mAm.updateForegroundServiceUsageStats(r.name, r.userId, false);
                if (r.app != null) {
                    mAm.updateLruProcessLocked(r.app, false, null);
                    updateServiceForegroundLocked(r.app.mServices, true);
                }
                updateNumForegroundServicesLocked();
            }
        }
    }

5.8.serviceForegroundTimeout

4.4.2调用,前台服务超时处理,处理的就是5.9的msg

    void serviceForegroundTimeout(ServiceRecord r) {
        ProcessRecord app;
        synchronized (mAm) {
            if (!r.fgRequired || !r.fgWaiting || r.destroying) {
            //非前台服务或者非前台服务等待中或者服务已销毁
                return;
            }

            app = r.app;
            if (app != null && app.isDebugging()) {
                //测试中,忽略
                return;
            }

            r.fgWaiting = false;
            //见补充1,停止服务
            stopServiceLocked(r, false);
        }

        if (app != null) {
        //就是说startForegroundService以后,需要在规定时间30s以内调用startForeground启动前台通知
            final String annotation = "Context.startForegroundService() did not then call "
                    + "Service.startForeground(): " + r;
            //4.4.3处理
            Message msg = mAm.mHandler.obtainMessage(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_ANR_MSG);
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = app;
            args.arg2 = annotation;
            msg.obj = args;
            mAm.mHandler.sendMessageDelayed(msg,
                    mAm.mConstants.mServiceStartForegroundAnrDelayMs);
        }
    }

>1.stopServiceLocked

    private void stopServiceLocked(ServiceRecord service, boolean enqueueOomAdj) {
        if (service.delayed) {
            //说明服务还没启动,只是在延迟启动的列表了,还是让它启动,一旦启动,立马停止
            service.delayedStop = true;
            return;
        }

        final int uid = service.appInfo.uid;
        final String packageName = service.name.getPackageName();
        final String serviceName = service.name.getClassName();

        mAm.mBatteryStatsService.noteServiceStopRunning(uid, packageName, serviceName);
        service.startRequested = false;
        if (service.tracker != null) {
            synchronized (mAm.mProcessStats.mLock) {
            //修改活动状态为false
                service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
                        SystemClock.uptimeMillis());
            }
        }
        service.callStart = false;
        //见补充2
        bringDownServiceIfNeededLocked(service, false, false, enqueueOomAdj);
    }

>2.bringDownServiceIfNeededLocked

    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
            boolean hasConn, boolean enqueueOomAdj) {
        //见补充3
        if (isServiceNeededLocked(r, knowConn, hasConn)) {
        //服务还需要
            return;
        }

        //服务还没启动
        if (mPendingServices.contains(r)) {
            return;
        }
        //见5.4.3
        bringDownServiceLocked(r, enqueueOomAdj);
    }

>3.isServiceNeededLocked

判断服务是否还需要

    private final boolean isServiceNeededLocked(ServiceRecord r, boolean knowConn,
            boolean hasConn) {
        // Are we still explicitly being asked to run?
        if (r.startRequested) {
            return true;
        }

        // Is someone still bound to us keeping us running?
        if (!knowConn) {
            //是否自动创建
            hasConn = r.hasAutoCreateConnections();
        }
        if (hasConn) {
            return true;
        }

        return false;
    }

5.9.scheduleServiceForegroundTransitionTimeoutLocked

参考5.4.4,服务启动以后会调用

  • 可以在这个方法里过滤包名,不启动超时检测服务,那么对应的前台服务也就不需要前台通知了。
    void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
        if (r.app.mServices.numberOfExecutingServices() == 0 || r.app.getThread() == null) {
            return;
        }
        //见4.4.2,前台服务启动超时msg,msg最终调用的是5.8的方法
        Message msg = mAm.mHandler.obtainMessage(
                ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
        msg.obj = r;
        r.fgWaiting = true; 
        //延迟时间是常量30秒
        mAm.mHandler.sendMessageDelayed(msg, mAm.mConstants.mServiceStartForegroundTimeoutMs);
    }

下边贴下启动超时msg啥时候被取消的

>1.setServiceForegroundInnerLocked

调用startForeground方法启动前台通知的时候会调用,见6.4

    private void setServiceForegroundInnerLocked(final ServiceRecord r, int id,
//..
        if (id != 0) {
//..
            if (r.fgRequired) {
                r.fgRequired = false;
                r.fgWaiting = false;
                alreadyStartedOp = stopProcStatsOp = true;
                //移除
                mAm.mHandler.removeMessages(
                        ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            }

>2.performScheduleRestartLocked

计划重启服务中

    void performScheduleRestartLocked(ServiceRecord r, @NonNull String scheduling,
            @NonNull String reason, @UptimeMillisLong long now) {

        if (r.fgRequired && r.fgWaiting) {
            mAm.mHandler.removeMessages(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
            r.fgWaiting = false;
        }

>3.bringDownServiceLocked

干掉服务的时候

    private void bringDownServiceLocked(ServiceRecord r, boolean enqueueOomAdj) {
    //..
        if (r.fgRequired) {
        //..
            mAm.mHandler.removeMessages(
                    ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);

5.10.serviceDoneExecutingLocked

Service完成了某种操作,小节7.4调用

    void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res,
            boolean enqueueOomAdj) {
        boolean inDestroying = mDestroyingServices.contains(r);
        if (r != null) {
            if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
                r.callStart = true;
                switch (res) {
                    case Service.START_STICKY_COMPATIBILITY:
                    case Service.START_STICKY: {//粘性服务
                        //移除投递集合里的数据
                        r.findDeliveredStart(startId, false, true);
                        //被杀死的时候是否停止服务
                        r.stopIfKilled = false;
                        break;
                    }
                    case Service.START_NOT_STICKY: {
                        r.findDeliveredStart(startId, false, true);
                        if (r.getLastStartId() == startId) {
                            r.stopIfKilled = true;
                        }
                        break;
                    }
            //..
            } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
            //..
            }
            serviceDoneExecutingLocked(r, inDestroying, inDestroying, enqueueOomAdj);
        } 
    }

5.11.realStartServiceLocked

真正的创建服务实例

    private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
            IApplicationThread thread, int pid, UidRecord uidRecord, boolean execInFg,
            boolean enqueueOomAdj) throws RemoteException {
        //更新进程信息
        r.setProcess(app, thread, pid, uidRecord);
        //更新下重启时间,最后的活动时间
        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();

        final ProcessServiceRecord psr = app.mServices;
        //主要就是加入已启动的服务集合里,并非真正的启动服务
        final boolean newService = psr.startService(r);
        bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */);
        mAm.updateLruProcessLocked(app, false, null);
        updateServiceForegroundLocked(psr, /* oomAdj= */ false);
        mAm.enqueueOomAdjTargetLocked(app);
        mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);

        boolean created = false;
        try {
            final int uid = r.appInfo.uid;
            final String packageName = r.name.getPackageName();
            final String serviceName = r.name.getClassName();

            mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
            mAm.notifyPackageUse(r.serviceInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
             //这里是真正的创建服务,见7.3.2
            thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.mState.getReportedProcState());
            r.postNotification();
            created = true;
        }

        if (r.allowlistManager) {
            psr.mAllowlistManager = true;
        }
        //处理bindService数据
        requestServiceBindingsLocked(r, execInFg);

        updateServiceClientActivitiesLocked(psr, null, true);

        if (newService && created) {
        //新加入启动的服务,放入bound集合,方便后续bindService使用
            psr.addBoundClientUidsOfNewService(r);
        }
    //服务处于启动状态,且没有挂起的参数,那么伪造一个,这样它就可以调用onStartCommand方法了
        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                    null, null, 0));
        }
        //见5.4.4,上边伪造了一个数据加入集合
        sendServiceArgsLocked(r, execInFg, true);

        if (r.delayed) {//从延迟启动集合里移除
            getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
            r.delayed = false;
        }

        if (r.delayedStop) {//延迟停止的
            r.delayedStop = false;
            if (r.startRequested) {
                //停止服务
                stopServiceLocked(r, enqueueOomAdj);
            }
        }
    }

5.12.serviceForegroundTimeoutANR

    void serviceForegroundTimeoutANR(ProcessRecord app, String annotation) {
        mAm.mAnrHelper.appNotResponding(app, annotation);
    }

6.Service.java

6.1.setStartForegroundServiceStackTrace

  • StackTrace是Exception的子类,构造方法里传递异常提示文字
  • 启动前台服务的时候,先保存类名和异常对象,等到前台服务启动异常以后,再根据类名找到这个异常对象,然后抛出。
    /**
     * This keeps track of the stacktrace where Context.startForegroundService() was called
     * for each service class. We use that when we crash the app for not calling
     * {@link #startForeground} in time, in {@link ActivityThread#throwRemoteServiceException}.
     */
    @GuardedBy("sStartForegroundServiceStackTraces")
    private static final ArrayMap<String, StackTrace> sStartForegroundServiceStackTraces =
            new ArrayMap<>();

    //添加新的前台服务对应的异常
    public static void setStartForegroundServiceStackTrace(
            @NonNull String className, @NonNull StackTrace stacktrace) {
        synchronized (sStartForegroundServiceStackTraces) {
            sStartForegroundServiceStackTraces.put(className, stacktrace);
        }
    }

6.2.clearStartForegroundServiceStackTrace

//清除所有map数据
    private void clearStartForegroundServiceStackTrace() {
        synchronized (sStartForegroundServiceStackTraces) {
            sStartForegroundServiceStackTraces.remove(this.getClassName());
        }
    }

6.3.getStartForegroundServiceStackTrace

    //根据类名获取异常对象
    public static StackTrace getStartForegroundServiceStackTrace(@NonNull String className) {
        synchronized (sStartForegroundServiceStackTraces) {
            return sStartForegroundServiceStackTraces.get(className);
        }
    }

6.4.startForeground

    public final void startForeground(int id, Notification notification) {
        try {
        //最终走到5.6
            mActivityManager.setServiceForeground(
                    new ComponentName(this, mClassName), mToken, id,
                    notification, 0, FOREGROUND_SERVICE_TYPE_MANIFEST);
            //见6.2,清除保存在异常map里的数据
            clearStartForegroundServiceStackTrace();
        } catch (RemoteException ex) {
        }
    }
    public final void startForeground(int id, @NonNull Notification notification,
            @ForegroundServiceType int foregroundServiceType) {
        try {
            mActivityManager.setServiceForeground(
                    new ComponentName(this, mClassName), mToken, id,
                    notification, 0, foregroundServiceType);
            //见6.2
            clearStartForegroundServiceStackTrace();
        } catch (RemoteException ex) {
        }
    }

6.5.stopForeground

    public final void stopForeground(boolean removeNotification) {
        stopForeground(removeNotification ? STOP_FOREGROUND_REMOVE : STOP_FOREGROUND_LEGACY);
    }
    public final void stopForeground(@StopForegroundSelector int notificationBehavior) {
        try {//见5.6
            mActivityManager.setServiceForeground(
                    new ComponentName(this, mClassName), mToken, 0, null,
                    notificationBehavior, 0);
        } catch (RemoteException ex) {
        }
    }

>1.StopForegroundSelector

            STOP_FOREGROUND_LEGACY, //0
            STOP_FOREGROUND_REMOVE, //1
            STOP_FOREGROUND_DETACH //2

7.ActivityThread.java

7.1.Handler

    class H extends Handler {

>1.SCHEDULE_CRASH

                case SCHEDULE_CRASH: {
                    SomeArgs args = (SomeArgs) msg.obj;
                    String message = (String) args.arg1;
                    Bundle extras = (Bundle) args.arg2;
                    args.recycle();
                    //见7.2.1
                    throwRemoteServiceException(message, msg.arg1, extras);
                    break;
                }

7.2.scheduleCrash

        public void scheduleCrash(String msg, int typeId, @Nullable Bundle extras) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = msg;
            args.arg2 = extras;
            //见7.1.1
            sendMessage(H.SCHEDULE_CRASH, args, typeId);
        }

>1.throwRemoteServiceException

抛出服务异常,根据type不同,异常也不同

    private void throwRemoteServiceException(String message, int typeId, @Nullable Bundle extras) {
        // Use a switch to ensure all the type IDs are unique.
        switch (typeId) {
            //前台服务没有在规定时间启动
            case ForegroundServiceDidNotStartInTimeException.TYPE_ID:
            //见补充2
                throw generateForegroundServiceDidNotStartInTimeException(message, extras);

            case CannotDeliverBroadcastException.TYPE_ID:
                throw new CannotDeliverBroadcastException(message);

            case CannotPostForegroundServiceNotificationException.TYPE_ID:
                throw new CannotPostForegroundServiceNotificationException(message);

            case BadForegroundServiceNotificationException.TYPE_ID:
                throw new BadForegroundServiceNotificationException(message);

            case MissingRequestPasswordComplexityPermissionException.TYPE_ID:
                throw new MissingRequestPasswordComplexityPermissionException(message);

            case CrashedByAdbException.TYPE_ID:
                throw new CrashedByAdbException(message);

            default:
                throw new RemoteServiceException(message
                        + " (with unwknown typeId:" + typeId + ")");
        }
    }

>2.generateForegroundServiceDidNotStartInTimeException

    private ForegroundServiceDidNotStartInTimeException
            generateForegroundServiceDidNotStartInTimeException(String message, Bundle extras) {
        //根据key="serviceclassname"获取服务类名
        final String serviceClassName =
                ForegroundServiceDidNotStartInTimeException.getServiceClassNameFromExtras(extras);
        //根据类名找到之前保存的异常对象,见6.3
        final Exception inner = (serviceClassName == null) ? null
                : Service.getStartForegroundServiceStackTrace(serviceClassName);
        //抛出远程异常
        throw new ForegroundServiceDidNotStartInTimeException(message, inner);
    }

7.3.ApplicationThread

>1.scheduleServiceArgs

更新服务参数,一般是服务已经启动了,再次调用start或者bindService等

        public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                s.taskRemoved = ssa.taskRemoved;
                s.startId = ssa.startId;
                s.flags = ssa.flags;
                s.args = ssa.args;

                sendMessage(H.SERVICE_ARGS, s);
            }
        }

>2.scheduleCreateService

创建新的服务

        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

7.4.handleServiceArgs

    private void handleServiceArgs(ServiceArgsData data) {
        CreateServiceData createData = mServicesData.get(data.token);
        Service s = mServices.get(data.token);
        if (s != null) {
            try {
                if (data.args != null) {
                    data.args.setExtrasClassLoader(s.getClassLoader());
                    data.args.prepareToEnterProcess(isProtectedComponent(createData.info),
                            s.getAttributionSource());
                }
                int res;
                if (!data.taskRemoved) {
                //调用服务onStartCommand方法
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } else {//task被移除,调用服务对应的方法
                    s.onTaskRemoved(data.args);
                    res = Service.START_TASK_REMOVED_COMPLETE;
                }

                QueuedWork.waitToFinish();

                try {//见5.10
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } 
            } 
        }
    }

7.5.handleCreateService

    private void handleCreateService(CreateServiceData data) {
        //取消gc操作
        unscheduleGcIdler();
        //获取安装包信息
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
            //获取应用的application对象
            Application app = packageInfo.makeApplicationInner(false, mInstrumentation);

            final java.lang.ClassLoader cl;
            if (data.info.splitName != null) {
                cl = packageInfo.getSplitClassLoader(data.info.splitName);
            } else {
                cl = packageInfo.getClassLoader();
            }
            //实例化一个服务对象
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
            //服务的上下文
            ContextImpl context = ContextImpl.getImpl(service
                    .createServiceBaseContext(this, packageInfo));
            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);
            }
            // Service resources must be initialized with the same loaders as the application
            // context.
            context.getResources().addLoaders(
                    app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

            context.setOuterContext(service);
            //调用attach方法
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            //调用onCreate方法
            service.onCreate();
            //数据存入map
            mServicesData.put(data.token, data);
            mServices.put(data.token, service);
            try {
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } 
        }
    }

8.ProcessRecord.java

8.1.scheduleCrashLocked

    void scheduleCrashLocked(String message, int exceptionTypeId, @Nullable Bundle extras) {
        //
        if (!mKilledByAm) {
            if (mThread != null) {
                if (mPid == Process.myPid()) {
                    //系统进程
                    return;
                }
                final long ident = Binder.clearCallingIdentity();
                try {//见7.2.
                    mThread.scheduleCrash(message, exceptionTypeId, extras);
                }
            }
        }
    }

9.AppErrors.java

9.1.scheduleAppCrashLocked

引起给定的app崩溃

    void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
            String message, boolean force, int exceptionTypeId, @Nullable Bundle extras) {
        ProcessRecord proc = null;
        //根据参数先查找到进程
        synchronized (mService.mPidsSelfLocked) {
            for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
                ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
                if (uid >= 0 && p.uid != uid) {
                    continue;
                }
                if (p.getPid() == initialPid) {
                    proc = p;
                    break;
                }
                if (p.getPkgList().containsKey(packageName)
                        && (userId < 0 || p.userId == userId)) {
                    proc = p;
                }
            }
        }

        if (proc == null) {
            //没找到进程
            return;
        }
        //异常类型 是 adb异常
        if (exceptionTypeId == CrashedByAdbException.TYPE_ID) {
            String[] packages = proc.getPackageList();
            for (int i = 0; i < packages.length; i++) {
                if (mService.mPackageManagerInt.isPackageStateProtected(packages[i], proc.userId)) {
                //pkg受保护
                    return;
                }
            }
        }
        //见8.1,计划崩溃
        proc.scheduleCrashLocked(message, exceptionTypeId, extras);
        if (force) {
            //强制的话,过5秒杀死应用
            final ProcessRecord p = proc;
            mService.mHandler.postDelayed(
                    () -> {
                        synchronized (mService) {
                            synchronized (mProcLock) {
                                killAppImmediateLSP(p, ApplicationExitInfo.REASON_OTHER,
                                        ApplicationExitInfo.SUBREASON_INVALID_STATE,
                                        "forced", "killed for invalid state");
                            }
                        }
                    },
                    5000L);
        }
    }

10.ServiceRecord.java

  • android:persistent 是一个用于控制应用程序特殊持久模式的标志。通常情况下不应被应用程序使用,它要求系统始终保持应用程序的运行。

10.1.getTracker

返回服务追踪器

    public ServiceState getTracker() {
        if (tracker != null) {
            return tracker;
        }
        //非持久应用
        if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
            //有旧的返回旧的,没有创建一个新的放入集合并返回
            tracker = ams.mProcessStats.getServiceState(serviceInfo.packageName,
                    serviceInfo.applicationInfo.uid,
                    serviceInfo.applicationInfo.longVersionCode,
                    serviceInfo.processName, serviceInfo.name);
            tracker.applyNewOwner(this);
        }
        return tracker;
    }

10.2.postNotification

显示通知

    public void postNotification() {
        if (isForeground && foregroundNoti != null && app != null) {
            final int appUid = appInfo.uid;
            final int appPid = app.getPid();
            final String localPackageName = packageName;
            final int localForegroundId = foregroundId;
            final Notification _foregroundNoti = foregroundNoti;
            final ServiceRecord record = this;

            ams.mHandler.post(new Runnable() {
                public void run() {
                    NotificationManagerInternal nm = LocalServices.getService(
                            NotificationManagerInternal.class);
                    if (nm == null) {
                        return;
                    }
                    //通知权限检查
                    mFgsHasNotificationPermission = nm.areNotificationsEnabledForPackage(
                            localPackageName, appUid);
                    Notification localForegroundNoti = _foregroundNoti;
                    try {
                        if (localForegroundNoti.getSmallIcon() == null) {
                                //没有设置小图标的话,这里重新创建了一个通知,用的应用的icon
                            //..
                                localForegroundNoti = notiBuilder.build();
                            } catch (PackageManager.NameNotFoundException e) {
                            }
                        }
                        if (nm.getNotificationChannel(localPackageName, appUid,
                                localForegroundNoti.getChannelId()) == null) {
                           //channel id为空,抛出异常
                        }
                        if (localForegroundNoti.getSmallIcon() == null) {
                            //还是没有小图标,抛出异常
                            throw new RuntimeException("invalid service notification: "
                                    + foregroundNoti);
                        }
                        //通知插入队列
                        nm.enqueueNotification(localPackageName, localPackageName,
                                appUid, appPid, null, localForegroundId, localForegroundNoti,
                                userId);

                        foregroundNoti = localForegroundNoti; // save it for amending next time
                    //回调处理
                        signalForegroundServiceNotification(packageName, appInfo.uid,
                                localForegroundId, false /* canceling */);

                    }
                }
            });
        }
    }