上一节咱们剖析到客户端发起 Binder RPC 调用,接下来就会长途调用到 SystemServer 进程中 ActivityTaskManagerService 服务的 startActivity 办法:

    // frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    @Override
    public int startActivityAsUser(IApplicationThread caller, String callingPackage,
            String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
            String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
            Bundle bOptions, int userId) {
        return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
                resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
                true /*validateIncomingUser*/);
    }

办法的参数有:

  • IApplicationThread caller:发动端 App 的 ActivityThread 方针中的 ApplicationThread 类型成员 mAppThread,在 App 端它是一个 Binder 服务端方针,到 SystemServer 端,通过 Binder 驱动和上层结构的处理,实践这个方针已经转换为 Binder 署理端方针了。SystemServer 端可以使用该方针向 App 端发起 RPC 调用,用于告诉 Activity 的状况改动
  • String callingPackage:发动方 Activity 所在包名 “com.android.launcher3”
  • String callingFeatureId:null
  • Intent intent:发动意图 Activity 的 Intent,携带了意图端 Acitivity 隐式或者显现发动需求的参数
  • String resolvedType: null,the MIME data type of this intent
  • IBinder resultTo:IBinder 方针,在 App 端是一个 Binder 署理方针,到 SystemServer 端,通过 Binder 驱动和上层结构的处理,实践这个方针已经是一个 Binder 服务端方针了,其值和发起端 Activity 的 ActivityRecord 方针中的 Token 成员相同,这个参数相对比较复杂,目前只需求知道,它可以作为一个索引找到对应的 ActivityRecord 方针
  • String resultWho:null
  • int requestCode:-1,发动意图端 Activity 的恳求码
  • int startFlags:Activity 的发动 flag,当时值为 0
  • ProfilerInfo profilerInfo:System private API for passing profiler settings,这儿是 null
  • Bundle bOptions:发动 Activity 的额定参数
  • userId:0

接着调用 startActivityAsUser:

    // frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    private int startActivityAsUser(IApplicationThread caller, String callingPackage,
            @Nullable String callingFeatureId, Intent intent, String resolvedType,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
        // ......
        // 关注点1
        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setCallingFeatureId(callingFeatureId)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(opts)
                .setUserId(userId)
                .execute();
    }

关注点 1 处,先调用 getActivityStartController 办法,办法中回来 ActivityTaskManagerService 类的成员变量 mActivityStartController。

    // base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    ActivityStartController getActivityStartController() {
        return mActivityStartController;
    }    

mActivityStartController 是 ActivityTaskManagerService 类的成员,ATMS 中 Activity 发动相关的功用都放在 ActivityStartController 类中:

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    // ......
    private ActivityStartController mActivityStartController;
    // ......
}

mActivityStartController 在 ActivityTaskManagerService 的 initialize 办法中初始化

    // base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
    public void initialize(IntentFirewall intentFirewall, PendingIntentController intentController,
            Looper looper) {
              // ......
              mActivityStartController = new ActivityStartController(this);
              // ......
    }
    // ActivityStartController 结构函数
    ActivityStartController(ActivityTaskManagerService service) {
        this(service, service.mStackSupervisor,
                new DefaultFactory(service, service.mStackSupervisor,
                    new ActivityStartInterceptor(service, service.mStackSupervisor)));
    }
    ActivityStartController(ActivityTaskManagerService service, ActivityStackSupervisor supervisor,
            Factory factory) {
        mService = service;
        mSupervisor = supervisor;
        mHandler = new StartHandler(mService.mH.getLooper());
        mFactory = factory;
        mFactory.setController(this);
        mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service,
                service.mH);
    }   

在 initialize 办法中,会去 new 一个 ActivityStartController 方针,在其结构函数中主要是对内部的成员进行赋值。

这儿需求要点关注的是 ActivityStartController 的成员 mFactory 初始化为 DefaultFactory 方针。后续会用到这个工厂类方针生成 ActivityStarter 方针。

回到发动进程代码,接着会调用 mActivityStartController 的 obtainStarter 办法:

    // frameworks/base/services/core/java/com/android/server/wm/ActivityStartController.java
    ActivityStarter obtainStarter(Intent intent, String reason) {
        return mFactory.obtain().setIntent(intent).setReason(reason);
    }

这儿的 mFactory 便是 ActivityStartController 初始化进程中的 DefaultFactory,会调用其 obtaion 办法初始化一个 ActivityStarter 方针回来。

    // frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
        @Override
        public ActivityStarter obtain() {
            ActivityStarter starter = mStarterPool.acquire();
            if (starter == null) {
                if (mService.mRootWindowContainer == null) {
                    throw new IllegalStateException("Too early to start activity.");
                }
                starter = new ActivityStarter(mController, mService, mSupervisor, mInterceptor);
            }
            return starter;
        }

这儿先从缓存里面去获取 ActivityStarter 方针,假如没有获取到,就 new 一个。当时情形下,会 new 一个 ActivityStarter 方针。

接着给 ActivityStarter 方针设置一堆参数,这些参数都来自 startActivityAsUser 办法的参数:

        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId)
                .execute();

到目前为止,起始便是构建了一个发动 Activity 的辅佐类 ActivityStarter 方针。

接着调用 ActivityStarter 的 execute 办法。

    // base/services/core/java/com/android/server/wm/ActivityStarter.java
    int execute() {
        try {
            // 发动 Activity 前的回调
            onExecutionStarted();
                // ......
                try {
                    // 发动 Activity
                    res = executeRequest(mRequest);
                } finally {
                    mRequest.logMessage.append(" result code=").append(res);
                    Slog.i(TAG, mRequest.logMessage.toString());
                    mRequest.logMessage.setLength(0);
                }
                // .......
        } finally {
            // 发动 Activity 后的回调
            onExecutionComplete();
        }
    }

接着咱们要点看 executeRequest 的完成:

    private int executeRequest(Request request) {
        if (TextUtils.isEmpty(request.reason)) {
            throw new IllegalArgumentException("Need to specify a reason.");
        }
        // 准备参数
        mLastStartReason = request.reason;
        mLastStartActivityTimeMs = System.currentTimeMillis();
        mLastStartActivityRecord = null;
        final IApplicationThread caller = request.caller;
        Intent intent = request.intent;
        NeededUriGrants intentGrants = request.intentGrants;
        String resolvedType = request.resolvedType;
        ActivityInfo aInfo = request.activityInfo;
        ResolveInfo rInfo = request.resolveInfo;
        final IVoiceInteractionSession voiceSession = request.voiceSession;
        final IBinder resultTo = request.resultTo;
        String resultWho = request.resultWho;
        int requestCode = request.requestCode;
        int callingPid = request.callingPid;
        int callingUid = request.callingUid;
        String callingPackage = request.callingPackage;
        String callingFeatureId = request.callingFeatureId;
        final int realCallingPid = request.realCallingPid;
        final int realCallingUid = request.realCallingUid;
        final int startFlags = request.startFlags;
        final SafeActivityOptions options = request.activityOptions;
        Task inTask = request.inTask;
        TaskFragment inTaskFragment = request.inTaskFragment;
        int err = ActivityManager.START_SUCCESS;
        // Pull the optional Ephemeral Installer-only bundle out of the options early.
        final Bundle verificationBundle =
                options != null ? options.popAppVerificationBundle() : null;
        WindowProcessController callerApp = null;
        if (caller != null) {
            // 获取调用者的进程信息
            // callerApp 的实践类型是 ProcessRecord
            callerApp = mService.getProcessController(caller);
            if (callerApp != null) {
                callingPid = callerApp.getPid();
                callingUid = callerApp.mInfo.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
                        + ") when starting: " + intent.toString());
                err = START_PERMISSION_DENIED;
            }
        }
        final int userId = aInfo != null && aInfo.applicationInfo != null
                ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
        final int launchMode = aInfo != null ? aInfo.launchMode : 0;
        if (err == ActivityManager.START_SUCCESS) { // 进入
            request.logMessage.append("START u").append(userId).append(" {")
                    .append(intent.toShortString(true, true, true, false))
                    .append("} with ").append(launchModeToString(launchMode))
                    .append(" from uid ").append(callingUid);
            if (callingUid != realCallingUid
                    && realCallingUid != Request.DEFAULT_REAL_CALLING_UID) {
                request.logMessage.append(" (realCallingUid=").append(realCallingUid).append(")");
            }
        }
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        if (resultTo != null) { // 进入
            // Launcher 端的 ActivityRecord
            sourceRecord = ActivityRecord.isInAnyTask(resultTo);
            if (DEBUG_RESULTS) {
                Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
            }
            if (sourceRecord != null) {
                if (requestCode >= 0 && !sourceRecord.finishing) {
                    resultRecord = sourceRecord;
                }
            }
        }
        final int launchFlags = intent.getFlags(); // 270532608
        // ......
        final Task resultRootTask = resultRecord == null
                ? null : resultRecord.getRootTask();
        if (err != START_SUCCESS) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            SafeActivityOptions.abort(options);
            return err;
        }
        boolean abort;
        try {
            // 权限检测
            // 当时场景,回来的 abort 为 false,表明有权限发动方针 Activity
            abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
                    request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
                    resultRootTask);
        } catch (SecurityException e) {
            // Return activity not found for the explicit intent if the caller can't see the target
            // to prevent the disclosure of package existence.
            final Intent originalIntent = request.ephemeralIntent;
            if (originalIntent != null && (originalIntent.getComponent() != null
                    || originalIntent.getPackage() != null)) {
                final String targetPackageName = originalIntent.getComponent() != null
                        ? originalIntent.getComponent().getPackageName()
                        : originalIntent.getPackage();
                if (mService.getPackageManagerInternalLocked()
                        .filterAppAccess(targetPackageName, callingUid, userId)) {
                    if (resultRecord != null) {
                        resultRecord.sendResult(INVALID_UID, resultWho, requestCode,
                                RESULT_CANCELED, null /* data */, null /* dataGrants */);
                    }
                    SafeActivityOptions.abort(options);
                    return ActivityManager.START_CLASS_NOT_FOUND;
                }
            }
            throw e;
        }
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
        abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
                callingPackage);
        // Merge the two options bundles, while realCallerOptions takes precedence.
        ActivityOptions checkedOptions = options != null
                ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
        // 后台发动权限处理
        @BalCode int balCode = BAL_ALLOW_DEFAULT;
        if (!abort) {
            try {
                Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
                        "shouldAbortBackgroundActivityStart");
                BackgroundActivityStartController balController =
                        mController.getBackgroundActivityLaunchController();
                balCode =
                        balController.checkBackgroundActivityStart(
                                callingUid,
                                callingPid,
                                callingPackage,
                                realCallingUid,
                                realCallingPid,
                                callerApp,
                                request.originatingPendingIntent,
                                request.backgroundStartPrivileges,
                                intent,
                                checkedOptions);
                if (balCode != BAL_ALLOW_DEFAULT) {
                    request.logMessage.append(" (").append(
                                    BackgroundActivityStartController.balCodeToString(balCode))
                            .append(")");
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
            }
        }
        if (request.allowPendingRemoteAnimationRegistryLookup) {
            checkedOptions = mService.getActivityStartController()
                    .getPendingRemoteAnimationRegistry()
                    .overrideOptionsIfNeeded(callingPackage, checkedOptions);
        }
        if (mService.mController != null) {
            try {
                // The Intent we give to the watcher has the extra data stripped off, since it
                // can contain private information.
                Intent watchIntent = intent.cloneFilter();
                abort |= !mService.mController.activityStarting(watchIntent,
                        aInfo.applicationInfo.packageName);
            } catch (RemoteException e) {
                mService.mController = null;
            }
        }
        // 拦截器
        mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
                callingFeatureId);
        if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
                callingPid, callingUid, checkedOptions)) {
            // activity start was intercepted, e.g. because the target user is currently in quiet
            // mode (turn off work) or the target application is suspended
            intent = mInterceptor.mIntent;
            rInfo = mInterceptor.mRInfo;
            aInfo = mInterceptor.mAInfo;
            resolvedType = mInterceptor.mResolvedType;
            inTask = mInterceptor.mInTask;
            callingPid = mInterceptor.mCallingPid;
            callingUid = mInterceptor.mCallingUid;
            checkedOptions = mInterceptor.mActivityOptions;
            // The interception target shouldn't get any permission grants
            // intended for the original destination
            intentGrants = null;
        }
        if (abort) {
            if (resultRecord != null) {
                resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
                        null /* data */, null /* dataGrants */);
            }
            // We pretend to the caller that it was really started, but they will just get a
            // cancel result.
            ActivityOptions.abort(checkedOptions);
            return START_ABORTED;
        }
        // If permissions need a review before any of the app components can run, we
        // launch the review activity and pass a pending intent to start the activity
        // we are to launching now after the review is completed.
        if (aInfo != null) {
            // // 运行时权限检测,当时情形下不进入
            if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
                    aInfo.packageName, userId)) {
                // ......
            }
        }
        // ......
        // 构建一个 ActivityRecord 方针
        final ActivityRecord r = new ActivityRecord.Builder(mService)
                .setCaller(callerApp)
                .setLaunchedFromPid(callingPid)
                .setLaunchedFromUid(callingUid)
                .setLaunchedFromPackage(callingPackage)
                .setLaunchedFromFeature(callingFeatureId)
                .setIntent(intent)
                .setResolvedType(resolvedType)
                .setActivityInfo(aInfo)
                .setConfiguration(mService.getGlobalConfiguration())
                .setResultTo(resultRecord)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setComponentSpecified(request.componentSpecified)
                .setRootVoiceInteraction(voiceSession != null)
                .setActivityOptions(checkedOptions)
                .setSourceRecord(sourceRecord)
                .build();
        mLastStartActivityRecord = r;
        if (r.appTimeTracker == null && sourceRecord != null) {
            // If the caller didn't specify an explicit time tracker, we want to continue
            // tracking under any it has.
            r.appTimeTracker = sourceRecord.appTimeTracker;
        }
        // Only allow app switching to be resumed if activity is not a restricted background
        // activity and target app is not home process, otherwise any background activity
        // started in background task can stop home button protection mode.
        // As the targeted app is not a home process and we don't need to wait for the 2nd
        // activity to be started to resume app switching, we can just enable app switching
        // directly.
        WindowProcessController homeProcess = mService.mHomeProcess;
        boolean isHomeProcess = homeProcess != null
                && aInfo.applicationInfo.uid == homeProcess.mUid;
        if (balCode != BAL_BLOCK && !isHomeProcess) {
            mService.resumeAppSwitches();
        }
        // 接着调用 startActivityUnchecked
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, checkedOptions,
                inTask, inTaskFragment, balCode, intentGrants, realCallingUid);
        if (request.outActivity != null) {
            request.outActivity[0] = mLastStartActivityRecord;
        }
        return mLastStartActivityResult;
    }

大致可分为 5 个阶段:

  • 准备一大堆参数
  • 各类权限检测
  • 发动进程拦截器处理
  • 构建待发动的方针 Activity 对应的 ActivityRecord 方针
  • 接着调用 startActivityUnchecked 办法

总结

流程很繁琐,实践中心的进程就三点:

  • 构建一个 Activity 发动的辅佐类 ActivityStarter 方针
  • 构建待发动的方针 Activity 对应的 ActivityRecord 方针
  • 接着调用 startActivityUnchecked 办法

参考资料