上一节咱们剖析到客户端发起 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 办法