文章出处:https://blog.csdn.net/shift_wwx/article/details/46467677
接着之前三篇
SystemServer中的ActivityManagerService.self().setWindowManager(wm);暂时不总结了,需要结合WMS。
接着总结:
ActivityManagerService.self().systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
try {
ActivityManagerService.self().startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
if (!headless) {
startSystemUi(contextF);
}
try {
if (mountServiceF != null) mountServiceF.systemReady();
} catch (Throwable e) {
reportWtf("making Mount Service ready", e);
}
......
......
}
};
这里systemReady的参数是一个Runnable的对象,并且实现了run,可以看到run里面都是AMS之后的一些准备工作。
例如startSystemUi、mountServiceF(MountService)、batteryF(BatteryService)、networkManagementF(NetworkManagementService)等等。
这些后续补充,来看一下systemReady的source code,由于systemReady的source code太长了,所以就分开来分析:
1、
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
if (mWaitingUpdate) {
return;
}
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
List<ResolveInfo> ris = null;
try {
ris = AppGlobals.getPackageManager().queryIntentReceivers(
intent, null, 0, 0);
} catch (RemoteException e) {
}
if (ris != null) {
for (int i=ris.size()-1; i>=0; i--) {
if ((ris.get(i).activityInfo.applicationInfo.flags
&ApplicationInfo.FLAG_SYSTEM) == 0) {
ris.remove(i);
}
}
intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
if (lastDoneReceivers.contains(comp)) {
ris.remove(i);
i--;
}
}
final int[] users = getUsersLocked();
for (int i=0; i<ris.size(); i++) {
ActivityInfo ai = ris.get(i).activityInfo;
ComponentName comp = new ComponentName(ai.packageName, ai.name);
doneReceivers.add(comp);
intent.setComponent(comp);
for (int j=0; j<users.length; j++) {
IIntentReceiver finisher = null;
if (i == ris.size()-1 && j == users.length-1) {
finisher = new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
// The raw IIntentReceiver interface is called
// with the AM lock held, so redispatch to
// execute our code without the lock.
mHandler.post(new Runnable() {
public void run() {
synchronized (ActivityManagerService.this) {
mDidUpdate = true;
}
writeLastDonePreBootReceivers(doneReceivers);
showBootMessage(mContext.getText(
R.string.android_upgrading_complete),
false);
systemReady(goingCallback);
}
});
}
};
}
Slog.i(TAG, "Sending system update to " + intent.getComponent()
+ " for user " + users[j]);
broadcastIntentLocked(null, null, intent, null, finisher,
0, null, null, null, AppOpsManager.OP_NONE,
true, false, MY_PID, Process.SYSTEM_UID,
users[j]);
if (finisher != null) {
mWaitingUpdate = true;
}
}
}
}
if (mWaitingUpdate) {
return;
}
mDidUpdate = true;
}
主要用来处理OTA升级后database有改变的状况,这里会从PMS中获取所有接收ACTION_PRE_BOOT_COMPLETED的Receivers,并发送广播给它们,最后会记录这些已经发送广播的Receivers到/data/system/called_pre_boots.dat文件中。关于OTA升级这部分我们先不关注了。
接着来看systemReady后面的代码:
2、
ArrayList<ProcessRecord> procsToKill = null;
synchronized(mPidsSelfLocked) {
for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
ProcessRecord proc = mPidsSelfLocked.valueAt(i);
if (!isAllowedWhileBooting(proc.info)){
if (procsToKill == null) {
procsToKill = new ArrayList<ProcessRecord>();
}
procsToKill.add(proc);
}
}
}
synchronized(this) {
if (procsToKill != null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
removeProcessLocked(proc, true, false, "system update done");
}
}
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
mProcessesReady = true;
}
上面的代码主要是杀死在AMS systemReady之前启动的启动process,且这些process没有设置FLAG_PERSISTENT(例如update进程),然后调用removeProcessLocked去结束进程并释放资源,这部分代码我们后面再来介绍。
3、retrieveSettings();
private void retrieveSettings() {
final ContentResolver resolver = mContext.getContentResolver();
String debugApp = Settings.Global.getString(
resolver, Settings.Global.DEBUG_APP);
boolean waitForDebugger = Settings.Global.getInt(
resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
boolean alwaysFinishActivities = Settings.Global.getInt(
resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
boolean forceRtl = Settings.Global.getInt(
resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
// Transfer any global setting for forcing RTL layout, into a System Property
SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
Configuration configuration = new Configuration();
Settings.System.getConfiguration(resolver, configuration);
if (forceRtl) {
// This will take care of setting the correct layout direction flags
configuration.setLayoutDirection(configuration.locale);
}
synchronized (this) {
mDebugApp = mOrigDebugApp = debugApp;
mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
mAlwaysFinishActivities = alwaysFinishActivities;
// This happens before any activities are started, so we can
// change mConfiguration in-place.
updateConfigurationLocked(configuration, null, false, true);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
}
}
从SettingsProvider中获取DEBUG_APP、WAIT_FOR_DEBUGGER、ALWAYS_FINISH_ACTIVITIES和DEVELOPMENT_FORCE_RTL四个配置项。
4、readGrantedUriPermissionsLocked
readGrantedUriPermissionsLocked从/data/system/urigrants.xml中读取Uri权限,并构造UriPermission保存在AMS全局的mGrantedUriPermissions中,这部分我们以后遇到的时候再来介绍。
5、if (goingCallback != null) goingCallback.run();
这里就是刚开始说到的,在systemServer中调用systemReady的时候同时注册的callback。
主要就是其他一些service 的systemReady、startSystemUi、软件启动Watchdog等。
6、mBooting = true;
7、mStackSupervisor.resumeTopActivitiesLocked();
boolean resumeTopActivitiesLocked() {
return resumeTopActivitiesLocked(null, null, null);
}
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = getFocusedStack();
}
boolean result = false;
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
if (isFrontStack(stack)) {
if (stack == targetStack) {
result = stack.resumeTopActivityLocked(target, targetOptions);
} else {
stack.resumeTopActivityLocked(null);
}
}
}
return result;
}
targetStack传进来的是null,所以,重新赋值为mHomeStack。记得ActivityStackSupervisor这个类吧?在AMS.main的时候实例化的。
刚开始的时候mStacks应该就一个mHomeStack,这里会调用到result = stack.resumeTopActivityLocked(target, targetOptions);这里的两个参数应该都是null:
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen("");
// Find the first activity that is not finishing.
ActivityRecord next = topRunningActivityLocked(null);
// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return mStackSupervisor.resumeHomeActivity(prev);
}
首先要获取next:
final ActivityRecord topRunningActivityLocked(ActivityRecord notTop) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ActivityRecord r = mTaskHistory.get(taskNdx).topRunningActivityLocked(notTop);
if (r != null) {
return r;
}
}
return null;
}
刚启动的时候mTaskHistory应该是空,所以,返回后next应该是null。
最终会调用return mStackSupervisor.resumeHomeActivity(prev);
boolean resumeHomeActivity(ActivityRecord prev) {
moveHomeToTop();
if (prev != null) {
prev.task.mOnTopOfHome = false;
}
ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
if (r != null && r.isHomeActivity()) {
mService.setFocusedActivityLocked(r);
return resumeTopActivitiesLocked(mHomeStack, prev, null);
}
return mService.startHomeActivityLocked(mCurrentUser, false);
}
r还是null,直接调用AMS的startHomeActivityLocked:
boolean startHomeActivityLocked(int userId, boolean preStart) {
if (mHeadless) {
// Added because none of the other calls to ensureBootCompleted seem to fire
// when running headless.
ensureBootCompleted();
return false;
}
if(preStart){
ensureBootCompleted();
}
if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
&& mTopAction == null) {
// We are running in factory test mode, but unable to find
// the factory test app, so just sit around displaying the
// error message and don't try to start anything.
return false;
}
Intent intent = getHomeIntent();
try {
//check if mount data fail
Boolean bMountFail = SystemProperties.getBoolean("ro.init.mountdatafail", false);
//Log.i( TAG, "bMountFail:" + bMountFail );
ComponentName name = new ComponentName("com.amlogic.promptuser", "com.amlogic.promptuser.BootActivity");
//PackageManager pm = mContext.getPackageManager();
//pm.setComponentEnabledSetting(name, bMountFail ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
final IPackageManager pm = AppGlobals.getPackageManager();
pm.setComponentEnabledSetting(name,
bMountFail ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP, userId);
} catch (Exception e) {
Log.w( TAG, "setComponentEnabledSetting with com.amlogic.promptuser boot activity fail" );
e.printStackTrace();
}
ActivityInfo aInfo =
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
if (aInfo != null) {
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't do this if the home app is currently being
// instrumented.
aInfo = new ActivityInfo(aInfo);
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mStackSupervisor.startHomeActivity(intent, aInfo);
}
}
return true;
}
1)getHomeIntent
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
mTopAction、mTopData、mTopComponent都是在AMS.main中调用的startRunning(null,null,null,null)中初始值的。
public final void startRunning(String pkg, String cls, String action,
String data) {
synchronized(this) {
if (mStartRunning) {
return;
}
mStartRunning = true;
mTopComponent = pkg != null && cls != null
? new ComponentName(pkg, cls) : null;
mTopAction = action != null ? action : Intent.ACTION_MAIN;
mTopData = data;
if (!mSystemReady) {
return;
}
}
systemReady(null);
}
可以看出mTopAction是Intent.ACTION_MAIN,mTopComponent是null。
那么综合看来getHomeIntent的目的就是实例化一个ACTION 是Intent.ACTION_MAIN、category是Intent.CATEGORY_HOME的一个intent。
2)通过之前获得的intent来解析ActivityInfo:
resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
ActivityInfo ai = null;
ComponentName comp = intent.getComponent();
try {
if (comp != null) {
ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
} else {
ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
flags, userId);
if (info != null) {
ai = info.activityInfo;
}
}
} catch (RemoteException e) {
// ignore
}
return ai;
}
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
if (!sUserManager.exists(userId)) return null;
enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
return chooseBestActivity(intent, resolvedType, flags, query, userId);
}
可能存在多个ACTION_MAIN,category是home的 intent,queryIntentActivities就是筛选,最开始的时候如果没有选择过会进入ResolverActivity (frameworks/base/core/java/com/android/internal/app) 让用户选择,至于怎么解析出ResolverActivity,我也是跟了一半,后期需要研究一下。如果有选择过了,就会通过chooseBestActivity函数来筛选:
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, int userId) {
if (query != null) {
final int N = query.size();
if (N == 1) {
return query.get(0);
} else if (N > 1) {
final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
// If there is more than one activity with the same priority,
// then let the user decide between them.
ResolveInfo r0 = query.get(0);
ResolveInfo r1 = query.get(1);
if (DEBUG_INTENT_MATCHING || debug) {
Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
+ r1.activityInfo.name + "=" + r1.priority);
}
// If the first activity has a higher priority, or a different
// default, then it is always desireable to pick it.
if (r0.priority != r1.priority
|| r0.preferredOrder != r1.preferredOrder
|| r0.isDefault != r1.isDefault) {
return query.get(0);
}
// If we have saved a preference for a preferred activity for
// this Intent, use that.
ResolveInfo ri = findPreferredActivity(intent, resolvedType,
flags, query, r0.priority, true, false, debug, userId);
if (ri != null) {
return ri;
}
if (userId != 0) {
ri = new ResolveInfo(mResolveInfo);
ri.activityInfo = new ActivityInfo(ri.activityInfo);
ri.activityInfo.applicationInfo = new ApplicationInfo(
ri.activityInfo.applicationInfo);
ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
return ri;
}
return mResolveInfo;
}
}
return null;
}
通过code可以看到,如果就一个home activity的话,就直接返回了。如果是多个的话就需要比较,例如priority、preferredOrder、isDefault等。
3)通过之前获取了ActivityInfo,就可以设置component了,当然第一次启动的时候如果home多个,这里的ActivityInfo肯定是ResolverActivity,如果是单个home,或者是经过筛选的,这里的ActivityInfo应该是筛选出来的。
ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true);
这里app显然null,于是进入:
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
mStackSupervisor.startHomeActivity(intent, aInfo);
Home 是一个新的task,最终看到了启动Home Activity的地方了。
接下来详细分析一下启动Home Activity的过程,以后单纯的启动一个activity也会有很多相似的地方。这里以android 的Launcher2为例。
void startHomeActivity(Intent intent, ActivityInfo aInfo) {
moveHomeToTop();//mTaskHistory 现在是空,这里没有做处理
startActivityLocked(null, intent, null, aInfo, null, null, 0, 0, 0, null, 0,
null, false, null);
}
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo, IBinder resultTo,
String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage, int startFlags, Bundle options,
boolean componentSpecified, ActivityRecord[] outActivity) {
int err = ActivityManager.START_SUCCESS;
ProcessRecord callerApp = null;
PackageManager mPm = mContext.getPackageManager();
if (caller != null) {//传进来参数为null
......
}
if (err == ActivityManager.START_SUCCESS) {
final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
+ "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
}
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {//传进来参数为null
......
}
ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
int launchFlags = intent.getFlags();
if ((launchFlags&Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0
&& sourceRecord != null) {//sourceRecord 为null
......
}
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {//component 不为null
......
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {//aInfo不为null
......
}
ResolveInfo info = mPm.resolveActivity(intent, PackageManager.GET_DISABLED_COMPONENTS);
//ResolveInfo info = mPm.resolveActivity(intent, PackageManager.GET_DISABLED_COMPONENTS|PackageManager.GET_INTENT_FILTERS);
String packageName = (info != null) ? info.activityInfo.applicationInfo.packageName : null;
String className = (info != null) ? info.activityInfo.name : null;
Slog.i(TAG, "start package name is " + packageName
+ ", class name is " + className
+ ", error code is " + err);//打印:
//I/ActivityManager( 506): start package name is com.android.launcher,
//class name is com.android.launcher2.Launcher, error code is 0
if (err != ActivityManager.START_SUCCESS) {
......
}
final int startAnyPerm = mService.checkPermission(
START_ANY_ACTIVITY, callingPid, callingUid);//返回值是PERMISSION_GRANTED
final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
callingUid, aInfo.applicationInfo.uid, aInfo.exported);
if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {
......
}
boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
if (mService.mController != null) {
......
}
if (abort) {
......
}
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified, this);
if (outActivity != null) {//传进来的参数是null
......
}
final ActivityStack stack = getFocusedStack();//mHomeStack
if (stack.mResumedActivity == null
|| stack.mResumedActivity.info.applicationInfo.uid != callingUid) {
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
......
}
}
if (mService.mDidAppSwitch) {
// This is the second allowed switch since we stopped switches,
// so now just generally allow switches. Use case: user presses
// home (switches disabled, switch to home, mDidAppSwitch now true);
// user taps a home icon (coming from home so allowed, we hit here
// and now allow anyone to switch again).
mService.mAppSwitchesAllowedTime = 0;
} else {
mService.mDidAppSwitch = true;
}
mService.doPendingActivityLaunchesLocked(false);
err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
if (allPausedActivitiesComplete()) {
// If someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
// switch... just dismiss the keyguard now, because we
// probably want to see whatever is behind it.
dismissKeyguard();
}
return err;
}
看一下code中添加的注释。
针对home来分析一下startActivityLocked 如果不是home activity,过程是不一样的。
1)r
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified, this);