[toc]
基于 Android 7.1.1
源码分析 AMS
的机制,本文为作者原创,转载请说明出处,谢谢!
0 综述
Android
系统开机时,在 SystemService
进程被 Zygote
启动后,SystemSevice
进程需要启动一些系统的重要服务:1
2
3
4Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();
startCoreServices();
startOtherServices();
AMS
的启动涉及到了以上的每个阶段,以为 AMS
需要和其他的系统服务进行交互,下面我们来逐一分析:
1 第一阶段 - startBootstrapServices
我们来看看低级阶段,和 AMS
相关的代码;
1 | private void startBootstrapServices() { |
- 启动
AMS
之前,需要先连接installd
进程, 通过Installer
这个服务,就能完成一些重要目录的创建,譬如/data/user
,同时应用程序的安装,也需要这个服务。 - 启动
ActivityManagerService
服务; - 启动
PowerManagerService
服务,AMS
需要使用PowerManagerService
的服务:譬如,在启动Activity
时,要避免系统进入休眠状态,就需要获取WakeLock
; - 启动
LightsService
、DisplayManagerService
、PackageManagerService
系统服务; - 启动
OtaDexoptService
服务,这里是和 A/B 升级相关的; - 调用
AMS.setSystemProcess()
设置当前进程为系统进程,设置系统进程相关的参数;- 因为
AMS
的职责之一就是维护系统中所有进程的状态,不管是应用进程还是系统进程,都是AMS
的管辖范围。
- 因为
接下来,我们来看看和 AMS
相关的流程!
1.1 ActivityManagerService
接下来,我们仔细的看看 AMS
的构造器!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147public ActivityManagerService(Context systemContext) {
// 获得系统进程的上下文环境;
mContext = systemContext;
mFactoryTest = FactoryTest.getMode(); // 是否是工厂模式!
// 获得 SystemServer 进程的 ActivityThread 对象,每个进程都有一个!
mSystemThread = ActivityThread.currentActivityThread();
Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
// 创建处理消息的 HandlerThread 和 Handler 对象!
mHandlerThread = new ServiceThread(TAG,
android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
// 创建处理 ANR 相关的 Handler!
mUiHandler = new UiHandler();
// 这里的 sKillHandler 绑定了一个 handlerThread 线程对象,用于处理杀进程的消息!
if (sKillHandler == null) {
sKillThread = new ServiceThread(TAG + ":kill",
android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
sKillThread.start();
sKillHandler = new KillHandler(sKillThread.getLooper());
}
// 集合管理前台广播和后台广播的集合,有前 / 后台之分,为了区分不同的广播消息超时时间。
mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
"foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
"background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[0] = mFgBroadcastQueue;
mBroadcastQueues[1] = mBgBroadcastQueue;
mServices = new ActiveServices(this); // 创建管理 Service 组件的 ActiveServices 对象!
mProviderMap = new ProviderMap(this); // 创建管理 Provider 组件的 ProviderMap 对象!
mAppErrors = new AppErrors(mContext, this); // 创建管理 ANR 和 crash 的 AppError 对象!
// 创建 /data/system 目录,诸如包管理packages.xml, packages.list等文件都存放于此目录
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
systemDir.mkdirs();
// 创建电量统计服务 BatteryStatsService 对象,并将 mHandler 传入,用于通信!
mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.scheduleWriteToDisk();
mOnBattery = DEBUG_POWER ? true
: mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
// 创建进程状态监控服务 ProcessStatsService 对象,/data/system/procstats 文件会存储
// 进程的状态信息!
mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
// 创建应用操作监控服务 AppOpsService 对象,/data/system/appops.xml文件存储app的
// 权限设置和操作信息!
mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
// 监听是否允许应用在后台运行的操作
mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
new IAppOpsCallback.Stub() {
public void opChanged(int op, int uid, String packageName) {
if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
if (mAppOpsService.checkOperation(op, uid, packageName)
!= AppOpsManager.MODE_ALLOWED) {
runInBackgroundDisabled(uid);
}
}
}
});
// 创建 urigrants.xml 文件对象!
mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
// 创建 UserController 对象!
mUserController = new UserController(this);
// 获取 OpenGL 版本号
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
mUseFifoUiScheduling = true;
}
mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
// 配置区域、语言、字体、屏幕方向等,启动 Activity 时,需要用到这个配置!
mConfiguration.setToDefaults();
mConfiguration.setLocales(LocaleList.getDefault());
mConfigurationSeq = mConfiguration.seq = 1;
// 初始化 processCpuTracker 对象,用来收集 ANR 情况下的 cpu 使用情况,电池状态等等!
mProcessCpuTracker.init();
// AndroidManifest.xml 中 compatible-screens 相关的解析工具
mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
// 创建 instent 防火墙!
mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
// 创建管理组件 Activity 的 ActivityStackSupervisor 和 ActivityStarter 对象!
mStackSupervisor = new ActivityStackSupervisor(this);
mActivityStarter = new ActivityStarter(this, mStackSupervisor);
// 创建最近任务对象!
mRecentTasks = new RecentTasks(this, mStackSupervisor);
// 创建一个子线程,不断循环,更新 cpu 的状态信息!
mProcessCpuThread = new Thread("CpuTracker") {
public void run() {
while (true) {
try {
try {
synchronized(this) {
final long now = SystemClock.uptimeMillis();
long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
//Slog.i(TAG, "Cpu delay=" + nextCpuDelay
// + ", write delay=" + nextWriteDelay);
if (nextWriteDelay < nextCpuDelay) {
nextCpuDelay = nextWriteDelay;
}
if (nextCpuDelay > 0) {
mProcessCpuMutexFree.set(true);
this.wait(nextCpuDelay);
}
}
} catch (InterruptedException e) {
}
// 更新 cpu 的状态以及电池状态信息!
updateCpuStatsNow();
} catch (Exception e) {
Slog.e(TAG, "Unexpected exception collecting process stats", e);
}
}
}
};
// 将自身加入到 Watchdog 的监控中!
Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
}
我们总结一下,在 AMS 的构造器中,主要做了一下几个事情:
创建了系统目录:
/data/system
创建了几个系统服务对象:
BatteryStatsService
:用于监控电池状态;ProcessStatsService
:用于监控进程状态;AppOpsService
:用于监控app
的操作行为;UserController
:
创建了四大组件的管理对象;
Broadcast
:mFgBroadcastQueue
和mBgBroadcastQueue
,分别管理前台后台广播;Service
:ActiveServices
;Provider
:ProviderMap
;Activity
:mStackSupervisor
,mActivityStarter
;
创建了处理
ANR
和Crash
的对象:mAppErrors
;- 创建最近任务对象:
RecentTasks
;
初次之外,还有:
- 初始化
processCpuTracker
对象! - 创建了几个
Handler
,用于消息处理:MainHandler
:绑定了子线程ServiceThread
对象mHandlerThread
,AMS
会把它传递个给其他服务,用于交互;UiHandler
:绑定了系统进程的主线程,用于处理ANR
和Crash
相关的信息!sKillThread
:绑定了子线程ServiceThread
对象sKillThread
,用于处理杀进程的操作;
- 创建几个子线程
- 一个线程
mProcessCpuThread
,不断的更新cpu
和电池的状态信息; - 两个
ServiceThread
子线程;
- 一个线程
1.1.1 new ActivityStackSupervisor
ActivityStackSupervisor
是系统中所有的 ActivityStack
的管理对象!1
2
3
4
5
6
7public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
// 创建了一个 ActivityStackSupervisorHandler 的 Handler 对象!
mHandler = new ActivityStackSupervisorHandler(mService.mHandler.getLooper());
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext);
mResizeDockedStackTimeout = new ResizeDockedStackTimeout(service, this, mHandler);
}
1.1.2 new ActivityStarter
ActivityStarter
对象负责启动 activity
:1
2
3
4
5ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
mService = service;
mSupervisor = supervisor;
mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
}
1.1.3 new RecentTasks
创建最近任务管理对象!1
2
3
4
5
6
7
8
9RecentTasks(ActivityManagerService service, ActivityStackSupervisor mStackSupervisor) {
// 对应 /data/system 目录
File systemDir = Environment.getDataSystemDirectory();
mService = service;
// 创建 TaskPersister 对象,用于管理那些重启后可恢复的任务!
mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, service, this);
// 将最近任务对象传递给 StackSupervisor!
mStackSupervisor.setRecentTasks(this);
}
TaskPersister
对象用于管理那些重启后可恢复的任务,下面我们去看看:
1.1.3.1 new TaskPersister
用于管理系统中所有的 persisable
类型的 task
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor,
ActivityManagerService service, RecentTasks recentTasks) {
// 删除目录:/data/system/recent_images 和其子目录!
final File legacyImagesDir = new File(systemDir, IMAGES_DIRNAME);
if (legacyImagesDir.exists()) {
if (!FileUtils.deleteContents(legacyImagesDir) || !legacyImagesDir.delete()) {
Slog.i(TAG, "Failure deleting legacy images directory: " + legacyImagesDir);
}
}
// 删除目录:/data/system/recent_tasks 和其子目录!
final File legacyTasksDir = new File(systemDir, TASKS_DIRNAME);
if (legacyTasksDir.exists()) {
if (!FileUtils.deleteContents(legacyTasksDir) || !legacyTasksDir.delete()) {
Slog.i(TAG, "Failure deleting legacy tasks directory: " + legacyTasksDir);
}
}
// 创建目录 :/data/system_de,保存了 persisable 任务的 id;
mTaskIdsDir = new File(Environment.getDataDirectory(), "system_de");
mStackSupervisor = stackSupervisor;
mService = service;
mRecentTasks = recentTasks;
// 创建一个线程对象,用于写数据!
mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThread");
}
这里我来简单的说一下:
- 在
/data/system_de
目录下,会有一个以设备用户id
命名的文件夹,内部会有一个名为persisted_taskIds.txt
的文件,内部保存了所有的persisable
类型的task
的id
;
1 | lishuaiqi:/data/system_de # ls -al |
- 在
/data/system_de
目录下,会有一个以设备用户id
命名的文件夹,内部会有两个文件夹:recent_images
和recent_tasks
:
1 | lishuaiqi:/data/system_ce/0 # ls -al |
其中,recent_images
用来保存 task
的截图信息,文件名的格式为:[task_id]_task_thumbnail.png
1
2
3lishuaiqi:/data/system_ce/0/recent_images # ls -al
-rw------- 1 system system 68019 2017-08-14 01:30 326_task_thumbnail.png
-rw------- 1 system system 18394 2017-08-14 01:30 327_task_thumbnail.png
其中,recent_tasks
用来保存 task
的信息,文件名的格式为:[task_id]_task.xml
1
2
3lishuaiqi:/data/system_ce/0/recent_tasks # ls -al
-rw------- 1 system system 1107 2017-08-14 16:58 279_task.xml
-rw------- 1 system system 1116 2017-08-19 19:06 320_task.xml
下面我们来看看 [task_id]_task.xml
文件中有那些奇葩的属性,这里以腾讯微信为例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37<task task_id="278"
real_activity="com.tencent.mm/.ui.LauncherUI"
real_activity_suspended="false"
affinity="com.tencent.mm"
root_has_reset="true"
auto_remove_recents="false"
asked_compat_mode="false"
user_id="0"
user_setup_complete="true"
effective_uid="10109"
task_type="0"
first_active_time="1502678072409"
last_active_time="1502678115558"
last_time_moved="1502678078477"
never_relinquish_identity="true"
task_description_color="ff212121"
task_description_colorBackground="fffafafa"
task_thumbnailinfo_task_width="1080"
task_thumbnailinfo_task_height="1920"
task_thumbnailinfo_screen_orientation="1"
task_affiliation_color="-14606047"
task_affiliation="278"
prev_affiliation="-1"
next_affiliation="-1"
calling_uid="10109"
calling_package="com.tencent.mm"
resize_mode="4"
privileged="false"
min_width="-1"
min_height="-1">
<intent action="android.intent.action.MAIN"
component="com.tencent.mm/.ui.LauncherUI"
flags="10200000">
<categories category="android.intent.category.LAUNCHER" />
</intent>
</task>
可以看到,所有的 persisable
类型的 task
,系统会将这些属性保存到对应的文件中,开机后可以恢复!
1.2 onStart
调用构造器,创建完 AMS
的对象之后,要做的就是启动 AMS
哦,在上一篇中,我们有看到,启动先调用 LifeCircle
的 onStart
,然后会调用了 AMS
的 start
方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private void start() {
// 移除所有的进程组!
Process.removeAllProcessGroups();
// 启动 ProcessCpuThread,监控 cpu 和电池的状态!
mProcessCpuThread.start();
// 将 BatteryStatsService 服务和 AppOpsService 注册到 ServiceManager 中,用于进程间通讯!
mBatteryStatsService.publish(mContext);
mAppOpsService.publish(mContext);
Slog.d("AppOps", "AppOpsService published");
// 将 AMS 添加进入 LocalServices 集合中,用于同一进程内的本地通信!
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
}
这个方法很简单,就不多说了:
- 移除所有的进程组;并启动
ProcessCpuThread
,监控cpu
和电池的状态! - 将
BatteryStatsService
服务和AppOpsService
注册到ServiceManager
中,用于Binder
通讯!
1.3 initPowerManagement
接下来,初始化 电池管理:1
2
3
4
5
6
7
8
9
10
11
12
13public void initPowerManagement() {
// 初始化电池管理!
mStackSupervisor.initPowerManagement();
mBatteryStatsService.initPowerManagement();
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
// 获得 WakeLock!
mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
mVoiceWakeLock.setReferenceCounted(false);
}
这里主要是进一步的初始化电池管理!
1.4 setSystemProcess
接下来,是设置 SytemServer 系统进程的相关信息,我们来看看代码,这里要仔细的来看了!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45public void setSystemProcess() {
try {
//【1】注册一些系统相关的服务
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
// 从 PackageManagerService 中获取 framework-res.apk (包名为 android) 的 ApplicationInfo 信息!
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
//【2】保存 framework-res.apk 的信息到系统进程的主线程中!
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
// 初始化系统进程的 ProcessRecord
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true; // 设置为常驻进程
app.pid = MY_PID; // 设置 pid
app.maxAdj = ProcessList.SYSTEM_ADJ; // 设置系统进程的 adj 为 -900,很难被杀死哦!
// 使系统进程处于活跃状态
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
// 将 systemServer 进程对象加入到 mPidsSelfLocked 中,以便管理!
mPidsSelfLocked.put(app.pid, app);
}
// 更新最近使用进程列表
updateLruProcessLocked(app, false, null);
// 用于更新进程的oom_adj值
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Unable to find android system package", e);
}
}
上面代码中用到了 mPidsSelfLocked
变量,我们看下这个变量的定义:1
final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
mPidsSelfLocked
保存有 pid
组织起来的正在运行的进程,保存的是 pid
,及 pid
对应的 ProcessRecord
。
这里我们来总结一下,这方法主要做了什么:
- 注册一些系统相关的服务,我们可以通过
adb shell dumpsys
命令查看! - 获取
framework-res.apk
安装包信息,保存到系统进程的ActivityThread
对象中! - 创建
SystemServer
系统进程的进程结构体,初始化属性,将其加入mPidsSelfLocked
,用于管理! - 更新进程的优先级和
oomAdj
,这两个方法,我们后面单开一贴!!!
下面我们仔细的看看一些细节,有利于我们对 AMS
的结构有一个更深层次的理解!
1.4.1 ServiceManager.addService
第一步,注册一些重要的服务,包括 ActivityManagerService 自身!1
2
3
4
5
6
7
8
9
10
11// 注册一些系统相关的服务
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
这里注册了哪些服务呢?这里用到了几个静态变量:
Context.ACTIVITY_SERVICE = “activity”;
ProcessStats.SERVICE_NAME = “procstats”;
这里注册了那些服务呢,我们来看看:
服务名 | 类名 | 功能 |
---|---|---|
procstats |
ProcessStatsService |
监控进程信息的服务 |
cpuinfo |
CpuBinder |
监控CPU信息的服务 |
meminfo |
MemBinder |
dump系统中每个进程的内存使用状况的服务 |
gfxinfo |
GraphicsBinder |
dump系统中每个进程使用图形加速卡状态的服务 |
dbinfo |
DbBinder |
dump 系统中每个进程的db状况的服务 |
permission |
PermissionController |
是检查Binder调用权限的服务 |
processinfo |
ProcessInfoService |
进程信息 |
这些服务我们先不细看,后面遇到了,再具体分析!
1.4.2 处理 framework-res.apk
接着,处理 framework-res.apk
安装包,在 PMS
的启动过程中,PackageManagerService
会扫描 framework-res.apk
的信息,并将信息封装成 ApplicaitonInfo
并保存在一个集合中:1
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
mSystemThread
对象是 ActvityThread
实例,每一个进程都有一个 ActivityThread
对象,内部保存着进程的主线程对象,这里保存着 SystemServer
进程的主线程对象!
我们继续看方法调用:
1.4.2.1 ActivityThread.installSystemApplicaitonInfo
我们进入 ActivityThread
的 installSystemApplicationInfo
的方法:1
2
3
4
5
6
7
8public void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
synchronized (this) {
//【1】调用 ContextImpl 对象的 installSystemApplicationInfo 方法!
getSystemContext().installSystemApplicationInfo(info, classLoader);
mProfiler = new Profiler();
}
}
getSystemContext
方法获得的是系统进程的 Context
对象,Context
的具体实现是 ContextImpl
类!
1.4.2.2 ContextImpl.installSystemApplicaitonInfo
进入 ContextImpl
对象中:1
2
3
4
5void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
//【1】调用 LoadedApk.installSystemApplicationInfo 方法;
mPackageInfo.installSystemApplicationInfo(info, classLoader);
}
其中 mPackageInfo
是 LoadedApk
对象,这里的 LoadedApk
是属于 SystemServer
进程的:
1.4.2.3 LoadedAPK.installSystemApplicaitonInfo
最后,将 framework-res.apk
的安装信息,保存到 SystemServer
进程的主线程的 LoadedAPK
对象中!1
2
3
4
5void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
assert info.packageName.equals("android");
mApplicationInfo = info;
mClassLoader = classLoader;
}
每一个进程都会有一个 LoadedApk
对象,最后 ApplicationInfo
和 ClassLoader
设置到了 LoadedApk
对象中!
1.4.3 newProcessRecordLocked
接下来,创建系统进程对应的 ProcessRecord
对象,传入参数:
info
:"framework-res.apk"
的ApplicationInfo
对象!customProcess
:info.processName
,所在进程名!isolated
:传入false
,表示不是隔离进程!isolatedUid
:传入0
,表示隔离进程的uid
;
isolated
和 isolatedUid
用来表示这进程是不是一个隔离进程!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
boolean isolated, int isolatedUid) {
String proc = customProcess != null ? customProcess : info.processName;
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
final int userId = UserHandle.getUserId(info.uid); // 获得所属的设备用户!
int uid = info.uid;
if (isolated) { // isolated 为 false, 不进入这个分支!
if (isolatedUid == 0) {
int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
while (true) {
if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
|| mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
}
uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
mNextIsolatedProcessUid++;
if (mIsolatedProcesses.indexOfKey(uid) < 0) {
// No process for this uid, use it.
break;
}
stepsLeft--;
if (stepsLeft <= 0) {
return null;
}
}
} else {
// Special case for startIsolatedProcess (internal only), where
// the uid of the isolated process is specified by the caller.
uid = isolatedUid;
}
}
//【1】创建 ProcessRecord,用于存储系统进程的信息
final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
if (!mBooted && !mBooting
&& userId == UserHandle.USER_SYSTEM
&& (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
r.persistent = true;
}
//【2】保存系统进程 ProcessRecord 对象到 AMS 的结构体中!
addProcessNameLocked(r);
return r;
}
接着,调用 addProcessNameLocked
方法:
1.4.3.1 addProcessNameLocked
保存系统进程 ProcessRecord
对象到 AMS
的结构体中!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34private final void addProcessNameLocked(ProcessRecord proc) {
//【1】如果已经有了相同的 ProcessRecord 对象,移除旧的!
ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
if (old == proc && proc.persistent) {
Slog.w(TAG, "Re-adding persistent process " + proc);
} else if (old != null) {
Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
}
//【2】创建 UidRecord 用来保存活跃的 uid,如果已经存在,就不创建!
UidRecord uidRec = mActiveUids.get(proc.uid);
if (uidRec == null) {
uidRec = new UidRecord(proc.uid);
// This is the first appearance of the uid, report it now!
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
"Creating new process uid: " + uidRec);
// 添加到 mActiveUids 对象!
mActiveUids.put(proc.uid, uidRec);
noteUidProcessState(uidRec.uid, uidRec.curProcState);
enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
}
proc.uidRecord = uidRec;
uidRec.numProcs++; // 所属该 uid 的进程计数加 1 (uid 代表一个应用程序)
//【3】非隔离进程保存到 mProcessNames 集合中,隔离进程保存到 mIsolatedProcesses 中!
mProcessNames.put(proc.processName, proc.uid, proc);
if (proc.isolated) {
mIsolatedProcesses.put(proc.uid, proc);
}
}
1.4.4 ProcessRecord.makeActive
参数传递:
thread
:mSystemThread.getApplicationThread()
,系统进程的ApplicationThread
对象!tracker
:mProcessStats
,是ProcessStatsService
服务对象,用来监听进程的状态!
1 | public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) { |
以上是在 SystemServer
启动系统服务的第一阶段做的一些主要的工作,接下来,我们来看第二阶段!
2 第二阶段 - startCoreServices
接下来,看看第二阶段的代码段:1
2
3
4
5
6
7
8
9
10
11
12private void startCoreServices() {
// 启动电池服务,必须是在 lightService 后启动 ;
mSystemServiceManager.startService(BatteryService.class);
//【1】启动应用统计服务,用于监控应用的使用频率等信息,并使得 AMS 持有其引用!
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// 启动 WebView 更新服务,这里不关注!
mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class);
}
这里我们看看 setUsageStatsManager
2.1 setUsageStatsManager
1 | public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { |
这个方法主要的作用是:
- 设置应用统计服务的应用,用于监控应用的使用频率等信息!
3 第三阶段 - startOtherServices
这里就要进入开机的最后阶段了,startOtherServices
方法非常的长,这里只列举和 ams
相关的代码!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106private void startOtherServices() {
try {
... ... ... ...
//【1】安装系统进程的 provider!
traceBeginAndSlog("InstallSystemProviders");
mActivityManagerService.installSystemProviders();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
... ... ... ...
// 初始化 watch dog 实例!
traceBeginAndSlog("InitWatchdog");
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// 启动 InputManagerService 和 WindowManagerService 服务!
traceBeginAndSlog("StartInputManagerService");
inputManager = new InputManagerService(context);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartWindowManagerService");
wm = WindowManagerService.main(context, inputManager,
mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
!mFirstBoot, mOnlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
... ... ... ...
//【2】将 WMS 的引用实例保存到 ams 中!
mActivityManagerService.setWindowManager(wm);
inputManager.setWindowManagerCallbacks(wm.getInputMonitor());
inputManager.start();
... ... ... ...
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
}
... ... ... ...
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
... ... ... ...
try {
wm.systemReady();
} catch (Throwable e) {
reportWtf("making Window Manager Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
if (safeMode) {
mActivityManagerService.showSafeModeOverlay();
}
// 更新显示相关的配置!
Configuration config = wm.computeNewConfiguration();
DisplayMetrics metrics = new DisplayMetrics();
WindowManager w = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
w.getDefaultDisplay().getMetrics(metrics);
context.getResources().updateConfiguration(config, metrics);
// 重置系统主题,因为可能依赖显示配置!
final Theme systemTheme = context.getTheme();
if (systemTheme.getChangingConfigurations() != 0) {
systemTheme.rebase();
}
... ... ... ...
//【3】进入 AMS 的 systemReady 方法,Runnable 任务中只要是启动一些其他的服务,这里我就省略了!
mActivityManagerService.systemReady(new Runnable() {
public void run() {
Slog.i(TAG, "Making services ready");
... ... ... ...
try {
// 开始监听 native crash!
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
... ... ... ...
// 启动 watch dog!
Watchdog.getInstance().start();
... ... ... ...
}
});
}
3.1 AMS.installSystemProviders
安装系统数据库:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
//【1】获取系统进程的 ProcessRecord, 之前 setSystemProcess() 时,创建了系统进程对应的 ProcessRecord
ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
//【2】生成 ProviderInfo 的列表!
providers = generateApplicationProvidersLocked(app);
if (providers != null) {
for (int i=providers.size()-1; i>=0; i--) {
ProviderInfo pi = (ProviderInfo)providers.get(i);
if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Not installing system proc provider " + pi.name
+ ": not system .apk");
//【2.1】移除一些非系统的 provider!
providers.remove(i);
}
}
}
}
if (providers != null) {
//【3】调用系统进程的 ActivityThread 的 installSystemProviders 方法,安装系统进程的数据库!
mSystemThread.installSystemProviders(providers);
}
mCoreSettingsObserver = new CoreSettingsObserver(this);
mFontScaleSettingObserver = new FontScaleSettingObserver();
//mUsageStatsService.monitorPackages();
}
这里指定了进程名为 system
,进程 uid
为 Process.SYSTEM_UID
,一般来说,会有以下 Provider
会出现在返回结果中:
framework-res.apk
中的Provider
, 定义在:frameworks/base/core/res/AndroidManifest.xml
SettingsProvider.apk
中的Provider
, 定义在:frameworks/base/packages/SettingsProvider/AndroidManifest.xml
对于手机厂商,可以对系统 apk
进行定制,比如让系统 apk
共享系统 uid
,这样的话,就不止以上两种 provider
了!
3.1.1 AMS.generateApplicationProvidersLocked
参数传递:
ProcessRecord app
:系统进程的ProcessRecord
对象!
1 | private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { |
我们通过一张类图,简单的了解一下 AMS
是如何管理 ContentProvider
的:
AMS
为每一个ContentProvider
创建了一个ContentProviderRecord
对象,ContentProviderRecord
中保存着provider
的配置信息providerInfo
;provider
所属进程的uid
;provider
所属应用的ApplicaitonInfo
对象!AMS
的mProviderMap
对象管理着系统中所有的ContentProviderRecord
对象,其内部保存着Authority
或者CompnentName
到指定ContentProviderRecord
的映射!AMS
内部还维护着和ProcessRecord
相关的集合,用于管理进程,有前台进程集合,内存常驻进程集合,最近使用的进程等等,当AMS
将一个ContentProviderRecord
与ProcessRecord
关联时,会将它保存到ProcessRecord
内部的一个pubProviders
集合中!
3.1.2 ActivityThread.installSystemProviders
接着调用 systemserver
进程的 ActivityThread
的 installSystemProvider
方法:1
2
3
4
5
6
7public final void installSystemProviders(List<ProviderInfo> providers) {
if (providers != null) {
//【1】mInitialApplication 是 SystemServer 的进程的 Application 对象!
installContentProviders(mInitialApplication, providers);
}
}
这里的 mInitialApplication
是系统进程的 Application
对象,接着调用了 installContentProviders
方法!
3.1.3 ActivityThread.installContentProviders
1 | private void installContentProviders(Context context, List<ProviderInfo> providers) { |
所有 ContentProvider
的创建都需要经过 installContentProvider()
函数,这个地方调用了 ActivityThread.installProvider
方法,继续安装 provider
!
3.1.3.1 ActivityThread.installProvider
让我们来继续看看这部分的代码 installProvider
,参数传递:
Context context
:传入context
对象,这里的context
是mInitialApplication
对象,是系统进程的上下文运行环境;IActivityManager.ContentProviderHolder holder
:传入null
;ProviderInfo info
:传入ProviderInfo
对象,封装着provider
的信息;boolean noisy
:传入false
;boolean noReleaseNeeded
:传入true
;boolean stable
:传入true
;
接着来看:
1 | private IActivityManager.ContentProviderHolder installProvider(Context context, |
首先,找到
ProviderInfo
对应的运行环境Context
:- 对于
framework-res.apk
中定义的com.android.server.am.DumpHeapProvider
而言,重新设置的Context
就是mInitialApplication
,所以就直接使用; - 对于
SettingProvider.apk
中定义的SettingsProvider
而言,它的包名为com.android.providers.settings
,不等于mInitialApplication
的包名android
,所以,会通过Context.createPackageContext()
函数创建一个新的Context
实例!
- 对于
接着,反射创建
ContentProvider
对象,然后,根据反射对象ContentProvider
,创建对应的ContentProviderHolder
对象!
3.1.3.2 AactivityManagerN.publishContentProviders
最终会调用 ActivityManagerService
中的 publishContentProviders
方法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
return;
}
enforceNotIsolatedCaller("publishContentProviders");
synchronized (this) {
//【1】获得调用者所在进程的 ProcessRecord 对象!
final ProcessRecord r = getRecordForAppLocked(caller);
if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
if (r == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
+ " (pid=" + Binder.getCallingPid()
+ ") when publishing content providers");
}
final long origId = Binder.clearCallingIdentity();
//【2】遍历传入的 ContentProviderHolder 集合!
final int N = providers.size();
for (int i = 0; i < N; i++) {
ContentProviderHolder src = providers.get(i);
if (src == null || src.info == null || src.provider == null) {
continue;
}
// 从 ProcessRecord 中获得其对应的 ContentProviderRecord 对象!
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
if (dst != null) {
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
// 将其保存到 AMS 的 mProviderMap 中!
mProviderMap.putProviderByClass(comp, dst);
String names[] = dst.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProviderMap.putProviderByName(names[j], dst);
}
int launchingCount = mLaunchingProviders.size();
int j;
boolean wasInLaunchingProviders = false;
for (j = 0; j < launchingCount; j++) {
if (mLaunchingProviders.get(j) == dst) {
// 从正在启动的 provider 列表中删除!
mLaunchingProviders.remove(j);
wasInLaunchingProviders = true;
j--;
launchingCount--;
}
}
if (wasInLaunchingProviders) {
mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
}
synchronized (dst) {
dst.provider = src.provider;
dst.proc = r;
dst.notifyAll();
}
// 更新 ommAdj 值,用于 LMK!
updateOomAdjLocked(r);
// 更新 provider 的使用状态!
maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
src.info.authority);
}
}
Binder.restoreCallingIdentity(origId);
}
}
关于 ContentProvider
的实现原理,我后续会有对应的博文分析,这里就不多说了!
3.1.3 阶段总结
我们总结一下:
首先,获得系统进程的
providerInfo
列表!- 通过 PMS,获得系统进程的
providerInfo
列表; - 确保系统进程
ProcessRecord
有足够的空间存储ContentProvider
; - 然后,对找到的
ProviderInfo
列表进行遍历, 如有需要, 则新建一个ContentProviderRecord
对象, 将其添加到AMS.mProviderMap
中以方便管理;同时, 也需要将其添加到PrcoessRecord.mPubProviders
中。 - 最后返回
providerInfo
列表;
- 通过 PMS,获得系统进程的
将
provider
注册到系统进程!
3.2 ActivityManagerS.setWindowManager
接着是就是设置 wms
的引用对象!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33void setWindowManager(WindowManagerService wm) {
synchronized (mService) {
//【1】设置 wms 引用实例
mWindowManager = wm;
//【2】获得 dms 的引用实力,并将 ams 注册进入 dms!
mDisplayManager =
(DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE);
mDisplayManager.registerDisplayListener(this, null);
//【3】通过 dms 获得是当前安卓设备所有有效的逻辑显示器列表!
Display[] displays = mDisplayManager.getDisplays();
for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) {
final int displayId = displays[displayNdx].getDisplayId();
// 为每一个显示器创建一个 ActivityDisplay 对象,存储该显示器的信息;
ActivityDisplay activityDisplay = new ActivityDisplay(displayId);
if (activityDisplay.mDisplay == null) {
throw new IllegalStateException("Default Display does not exist");
}
//【3.1】将其保存到 ams 的 mActivityDisplays 集合中,后续会用到!
mActivityDisplays.put(displayId, activityDisplay);
calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
}
//【4】初始化 mHomeStack,mFocusedStack 和 mLastFocusedStack 这三个 stack!
mHomeStack = mFocusedStack = mLastFocusedStack =
getStack(HOME_STACK_ID, CREATE_IF_NEEDED, ON_TOP);
//【5】通过本地服务过得 ims 的调用接口;
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
}
}
这个方法逻辑很简单!这里重点看一下,在系统启动的时候,会初始化 mFocusedStack
和 mLastFocusedStack
为 HOME_STACK_ID
类型的 stack
,这个是显而易见的,因为开机后,就会进入桌面,此时焦点 stack
一定是 home stack
!
3.2.1 ActivityStackSupervisor.getStack
该方法的作用是返回一个可用的 stack
,createStaticStackIfNeeded
表示有必要的话是否创建一个静态 stack
!
1 | ActivityStack getStack(int stackId, boolean createStaticStackIfNeeded, boolean createOnTop) { |
这里我们知道,在刚开机的时候,是没有任何的 ActivityContainer
的,所以这里会进入 createStackOnDisplay
方法中继续创建!
3.2.2 ActivityStackSupervisor.createStackOnDisplay
1 | ActivityStack createStackOnDisplay(int stackId, int displayId, boolean onTop) { |
这里其实很简单,针对于指定的显示器 ActivityDisplay
,创建对应的 ActivityContainer
,然后 ActivityContainer
内部再去创建 ActivityStack
!
3.2.2.1 new ActivityContainer
我们来去看看 ActivityContainer
的创建:
1 | class ActivityContainer extends android.app.IActivityContainer.Stub { |
我们再去看看 ActivityStack
的创建:
3.2.2.2.1 new ActivityStack
1 | ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, |
这里就不多说了!
3.2.2.2 ActivityContainer.attachToDisplayLocked
接下来就是很关键的一部,就是将 ActivityContainer
绑定到指定的 ActivityDisplay
对象上!
1 | void attachToDisplayLocked(ActivityDisplay activityDisplay, boolean onTop) { |
3.2.2.2.1 ActivityStack.attachDisplay
1 | void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) { |
3.2.2.2.2 ActivityDisplay.attachActivities
1 | void attachActivities(ActivityStack stack, boolean onTop) { |
其实,整个过程就是创建容器,建立引用关系的过程,通过分析,我们知道,安卓系统的所有的 stack
的创建都是这样的!!
3.3 ActivityManagerS.systemReady
SystemServer
在启动完所有服务之后,将调用 AMS
的 systemReady()
方法。这个方法是 Android
进入用户交互阶段前最后进行的准备工作。这里就即将进入开机的最后阶段了:
1 | public void systemReady(final Runnable goingCallback) { |
这里的代码逻辑比较复杂,里面有一些关键的点,我们来看看:
3.3.1 通知其他服务 - SystemReady
代码如下:1
2
3
4mUserController.onSystemReady();
mRecentTasks.onSystemReadyLocked();
mAppOpsService.systemReady();
mSystemReady = true;
我们一个一个来看:
3.3.1.1 UserController.onSystemReady
1 | void onSystemReady() { |
调用了 updateCurrentProfileIdsLocked
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23private void updateCurrentProfileIdsLocked() {
final List<UserInfo> profiles = getUserManager().getProfiles(mCurrentUserId,
false /* enabledOnly */);
int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
for (int i = 0; i < currentProfileIds.length; i++) {
currentProfileIds[i] = profiles.get(i).id;
}
mCurrentProfileIds = currentProfileIds;
synchronized (mUserProfileGroupIdsSelfLocked) {
mUserProfileGroupIdsSelfLocked.clear();
final List<UserInfo> users = getUserManager().getUsers(false);
// 保存所有设备用户的信息,用于以后权限校验使用!
for (int i = 0; i < users.size(); i++) {
UserInfo user = users.get(i);
if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
// 保存在这里!
mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
}
}
}
}
这个方法的作用是:Android
的许多系统调用都需要检查用户的 ID
,所以这里调用 updateCurrnetProfileIdsLocked()
方法来通过 UserManagerService
读取系统保持的 Profile
信息,装载系统中已经存在的用户信息。
3.3.1.2 RecentTasks.onSystemReady
代码如下:1
2
3
4void onSystemReadyLocked() {
clear();
mTaskPersister.startPersisting();
}
从 Android5.0
开始支持带有 persistent
标记的 task
,这些 task
在关机时,信息保存在 /data/system_ce/recent_tasks
目录下的 xxx_task.xml
(xxx
表示 task id
)中,系统重启时,通过这些文件中保存的信息重建 task
,和 JobSchedulerService
很类似哦!
1 | void startPersisting() { |
该方法中启动了一个 mLazyTaskWriterThread
的线程,恢复那些 pesistable
类型的 task
,这里不多说了!
3.3.1.3 AppOpsService.onSystemReady
这里调用了 AppOpsService
的 systemReady
,代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79public void systemReady() {
synchronized (this) {
boolean changed = false;
//【1】更新系统中所有的 uid 的状态!
for (int i = mUidStates.size() - 1; i >= 0; i--) {
UidState uidState = mUidStates.valueAt(i);
//【1.1】uid 对应的 package 为 null,移除该 uid!
String[] packageNames = getPackagesForUid(uidState.uid);
if (ArrayUtils.isEmpty(packageNames)) {
uidState.clear();
mUidStates.removeAt(i);
changed = true;
continue;
}
ArrayMap<String, Ops> pkgs = uidState.pkgOps;
if (pkgs == null) {
continue;
}
//【1.1】如果 uid 的某个 ops 发生变化,移除它!
Iterator<Ops> it = pkgs.values().iterator();
while (it.hasNext()) {
Ops ops = it.next();
int curUid = -1;
try {
curUid = AppGlobals.getPackageManager().getPackageUid(ops.packageName,
PackageManager.MATCH_UNINSTALLED_PACKAGES,
UserHandle.getUserId(ops.uidState.uid));
} catch (RemoteException ignored) {
}
if (curUid != ops.uidState.uid) {
Slog.i(TAG, "Pruning old package " + ops.packageName
+ "/" + ops.uidState + ": new uid=" + curUid);
it.remove();
changed = true;
}
}
if (uidState.isDefault()) {
mUidStates.removeAt(i);
}
}
//【1.3】如果 uid 的状态发生变化,将其持久化到本地文件中!
if (changed) {
scheduleFastWriteLocked();
}
}
//【2】获得挂载服务,设置外置存储挂载策略!
MountServiceInternal mountServiceInternal = LocalServices.getService(
MountServiceInternal.class);
mountServiceInternal.addExternalStoragePolicy(
new MountServiceInternal.ExternalStorageMountPolicy() {
public int getMountMode(int uid, String packageName) {
if (Process.isIsolated(uid)) {
return Zygote.MOUNT_EXTERNAL_NONE;
}
if (noteOperation(AppOpsManager.OP_READ_EXTERNAL_STORAGE, uid,
packageName) != AppOpsManager.MODE_ALLOWED) {
return Zygote.MOUNT_EXTERNAL_NONE;
}
if (noteOperation(AppOpsManager.OP_WRITE_EXTERNAL_STORAGE, uid,
packageName) != AppOpsManager.MODE_ALLOWED) {
return Zygote.MOUNT_EXTERNAL_READ;
}
return Zygote.MOUNT_EXTERNAL_WRITE;
}
public boolean hasExternalStorage(int uid, String packageName) {
final int mountMode = getMountMode(uid, packageName);
return mountMode == Zygote.MOUNT_EXTERNAL_READ
|| mountMode == Zygote.MOUNT_EXTERNAL_WRITE;
}
});
}
这个 AppOpsService
是谷歌原生的应用程序权限管理服务,在 Android M ( Android 6.0 )
加入的 Application Permission Manager
的功能就是基于 AppOps
实现的!
AppOps
全称是 Application Operations
,类似我们平时常说的应用程序的操作(权限)管理。目前 Google
在每次版本更新时都会隐藏掉 AppOps
的入口。
注意:AppOps
虽然涵盖了 App
的权限管理,但是 Google
原生的设计并不仅仅是对“权限”的管理,而是对 App
的“动作”的管理。我们平时讲的权限管理多是针对具体的权限(App
开发者在 Manifest
里申请的权限),而 AppOps
所管理的是所有可能涉及用户隐私和安全的操作,包括 access notification
, keep weak lock
, activate vpn
, display toast
等等,有些操作是不需要 Manifest
里申请权限的。
不多说了,这不多关注!
3.3.2 杀掉特定进程
刚刚有讲到,AMS
会杀掉已经启动并且没有带有 FLAG_PERSISTENT
标记的进程,那如何判断是否具有这个标记呢:
3.3.2.1 isAllowedWhileBooting
1 | boolean isAllowedWhileBooting(ApplicationInfo ai) { |
如果某个进程没有 FLAG_PERSISTENT
,这个方法会返回 false
!
3.3.3 读取设置信息 - retrieveSettings
该方法的目的是从前面已经配置好的系统 provider
中互动一些设置属性!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88private void retrieveSettings() {
final ContentResolver resolver = mContext.getContentResolver();
//【1】获得一些系统属性!
final boolean freeformWindowManagement =
mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
|| Settings.Global.getInt(
resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
// 是否支持画中画模式!
final boolean supportsPictureInPicture =
mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
// 是否支持分屏模式!
final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
final boolean alwaysFinishActivities =
Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
final boolean lenientBackgroundCheck =
Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
// 是否强制 RTL 显示!
final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
// 是否强制 activity 显示尺寸可变化!
final boolean forceResizable = Settings.Global.getInt(
resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
final boolean supportsLeanbackOnly =
mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
final 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);
}
//【2】根据获得的系统属性,初始化系统属性变量!
synchronized (this) {
mDebugApp = mOrigDebugApp = debugApp;
mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
mAlwaysFinishActivities = alwaysFinishActivities;
mLenientBackgroundCheck = lenientBackgroundCheck;
mSupportsLeanbackOnly = supportsLeanbackOnly;
mForceResizableActivities = forceResizable;
mWindowManager.setForceResizableTasks(mForceResizableActivities);
if (supportsMultiWindow || forceResizable) {
mSupportsMultiWindow = true;
mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
} else {
mSupportsMultiWindow = false;
mSupportsFreeformWindowManagement = false;
mSupportsPictureInPicture = false;
}
// This happens before any activities are started, so we can
// change mConfiguration in-place.
updateConfigurationLocked(configuration, null, true);
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Initial config: " + mConfiguration);
// Load resources only after the current configuration has been set.
final Resources res = mContext.getResources();
// 是否有最近任务!
mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
mThumbnailWidth = res.getDimensionPixelSize(
com.android.internal.R.dimen.thumbnail_width);
mThumbnailHeight = res.getDimensionPixelSize(
com.android.internal.R.dimen.thumbnail_height);
mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
com.android.internal.R.string.config_defaultPictureInPictureBounds));
mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
com.android.internal.R.string.config_appsNotReportingCrashes));
if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
mFullscreenThumbnailScale = (float) res
.getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
(float) mConfiguration.screenWidthDp;
} else {
mFullscreenThumbnailScale = res.getFraction(
com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
}
}
}
这里不多说了!
3.3.4 读取 Uri 权限信息
3.3.4.1 读取 Uri 权限信息
1 | private void readGrantedUriPermissionsLocked() { |
3.3.4.2 ActivityManagerS.findOrCreateUriPermissionLocked
1 | private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, |
mGrantedUriPermissions 用来保存系统中所有已经授予的 uri 权限!
下面去看看 UriPermission 对象!
1 | UriPermission(String sourcePkg, String targetPkg, int targetUid, GrantUri uri) { |
接着调用了 initPersistedModes 初始化 persisted 相关属性,包括 persistableModeFlags,persistedModeFlags 和 persistedCreateTime!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void initPersistedModes(int modeFlags, long createdTime) {
// 初始化 persistableModeFlags 和 persistedModeFlags
// 只包含 FLAG_GRANT_READ_URI_PERMISSION 和 FLAG_GRANT_WRITE_URI_PERMISSION!
modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
persistableModeFlags = modeFlags;
persistedModeFlags = modeFlags;
persistedCreateTime = createdTime;
updateModeFlags(); // 更新 modeFlags!
}
private void updateModeFlags() {
final int oldModeFlags = modeFlags;
modeFlags = ownedModeFlags | globalModeFlags | persistableModeFlags | persistedModeFlags;
if (Log.isLoggable(TAG, Log.VERBOSE) && (modeFlags != oldModeFlags)) {
Slog.d(TAG,
"Permission for " + targetPkg + " to " + uri + " is changing from 0x"
+ Integer.toHexString(oldModeFlags) + " to 0x"
+ Integer.toHexString(modeFlags),
new Throwable());
}
}
关于 UriPermission 我们这里只涉及这么多!
3.3.5 启动 persistent 进程 - startPersistentApps
1 | private void startPersistentApps(int matchFlags) { |
启动进程调用了 addAppLocked
,我们继续看!
3.3.5.1 ActivityManagerS.addAppLocked
1 | final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, |
关于进程的启动,请看我的另一系列的博文,这里就不多说了!
3.3.6 启动桌面进程
接着是启动桌面所在的进程:
3.3.6.1 startHomeActivityLocked
1 | boolean startHomeActivityLocked(int userId, String reason) { |
3.3.6.1.1 ActivityManagerS.getHomeIntent
1 | Intent getHomeIntent() { |
startHomeActivityLocked
方法最后会来自桌面 activity
的 onCreate
方法,然后,resumeFocusedStackTopActivityLocked
又会拉起桌面 activity
的 onResume
方法:
1 | mStackSupervisor.resumeFocusedStackTopActivityLocked(); |
对于 activity
的启动,这里我就不多讲了,请看我的其他博文!
到这里,桌面就完全显示在用户面前的,然而,还没有结束,我们进入到 ActivityThread
中去:
3.3.6.2 ActivityThread.handleResumeActivity
handleResumeActivity
负责拉起桌面 activity
的 onResume
方法,我们过滤掉一些不重要的代码:
1 | final void handleResumeActivity(IBinder token, |
当桌面进程的主线程进入空闲状态时,Idler.queueIdle
方法会被执行:
1 | private class Idler implements MessageQueue.IdleHandler { |
下面,进入 ActivityManagerService
中去:
3.3.6.3 ActivityManagerS.activityIdle
1 |
|
3.3.6.4 ActivityManagerS.activityIdleInternalLocked
这里我们只关注和 AMS
启动有关的代码!
1 | final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout, |
3.3.6.5 ActivityStackS.checkFinishBootingLocked
1 | private boolean checkFinishBootingLocked() { |
postFinishBooting
会通过 MainHandler
发送 FINISH_BOOTING_MSG
消息给子线程,子线程会调用 AMS.finishBooting
的方法!
3.3.6.6 ActivityManagerS.finishBooting
该方法就是最关键的地方了,我们的开机广播就是在这个地方发送的!!!1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112final void finishBooting() {
synchronized (this) {
//【1】如果开机动画没有显示完,则退出,等开机动画显示完后才会调用!
if (!mBootAnimationComplete) {
mCallFinishBooting = true;
return;
}
mCallFinishBooting = false;
}
// 检查系统 ABI,ABI 和系统 cpu 指令集有关!
ArraySet<String> completedIsas = new ArraySet<String>();
for (String abi : Build.SUPPORTED_ABIS) {
Process.establishZygoteConnectionForAbi(abi);
final String instructionSet = VMRuntime.getInstructionSet(abi);
if (!completedIsas.contains(instructionSet)) {
try {
mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
} catch (InstallerException e) {
Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
e.getMessage() +")");
}
completedIsas.add(instructionSet);
}
}
// 注册接收者,监听重启 package 的广播,当系统发送了该广播后,该广播会传递所有需要重启的 package
// 这里监听到该广播后,会重启所有的 package 的进程!
IntentFilter pkgFilter = new IntentFilter();
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
pkgFilter.addDataScheme("package");
mContext.registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
if (pkgs != null) {
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
}
}
}
}
}, pkgFilter);
// 注册接收者,监听 ACTION_DELETE_DUMPHEAP 广播!
IntentFilter dumpheapFilter = new IntentFilter();
dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
mContext.registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
} else {
mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
}
}
}, dumpheapFilter);
// 通知系统服务已经进入最后阶段:PHASE_BOOT_COMPLETED
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
synchronized (this) {
// 启动那些之前无法启动的进程,比如系统进程未准备好,且不是常驻进程等等!
final int NP = mProcessesOnHold.size();
if (NP > 0) {
ArrayList<ProcessRecord> procs =
new ArrayList<ProcessRecord>(mProcessesOnHold);
for (int ip=0; ip<NP; ip++) {
if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
+ procs.get(ip));
// 启动之前无法启动而被系统暂时监管的应用进程!
startProcessLocked(procs.get(ip), "on-hold", null);
}
}
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
// 设置系统属性!
SystemProperties.set("sys.boot_completed", "1");
if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
|| "".equals(SystemProperties.get("vold.encrypt_progress"))) {
SystemProperties.set("dev.bootcomplete", "1");
}
//【2】解锁设备用户,发送开机相关的广播!
mUserController.sendBootCompletedLocked(
new IIntentReceiver.Stub() {
public void performReceive(Intent intent, int resultCode,
String data, Bundle extras, boolean ordered,
boolean sticky, int sendingUser) {
synchronized (ActivityManagerService.this) {
requestPssAllProcsLocked(SystemClock.uptimeMillis(),
true, false);
}
}
});
scheduleStartProfilesLocked();
}
}
}
总体来看,逻辑不复杂,最后的一步很关键:1
mUserController.sendBootCompletedLocked(...);
该方法会发送一系列的开机广播,并且会解除所有启动完成的设备用户的锁定状态!
广播的发送顺序是:
1 | ACTION_LOCKED_BOOT_COMPLETED -> ACTION_PRE_BOOT_COMPLETED -> ACTION_BOOT_COMPLETED |
- ACTION_LOCKED_BOOT_COMPLETED
因为此时设备用户仍然处于锁定状态,该方法会首先发送 ACTION_LOCKED_BOOT_COMPLETED
广播,
这个广播的触发时机是:设备用户已经完成了启动,当时仍然处于锁定状态!
发生了该广播后,系统进程就会开始接触设备用户的锁定!!
- ACTION_PRE_BOOT_COMPLETED
当设备用户解除锁定后,就会发送这个广播,这个广播的发送时机是,系统升级后,设备的 FINGERPRINT
发生了变化!如果没有发生变化的话,会直接发送 ACTION_BOOT_COMPLETED
广播!
下面是核心代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33void finishUserUnlocked(final UserState uss) {
final int userId = uss.mHandle.getIdentifier();
synchronized (mService) {
... ... ... ...
if (uss.setState(STATE_RUNNING_UNLOCKING, STATE_RUNNING_UNLOCKED)) {
... ... ... ... ...
final UserInfo info = getUserInfo(userId);
if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) {
final boolean quiet;
if (info.isManagedProfile()) {
quiet = !uss.tokenProvided
|| !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId);
} else {
quiet = false;
}
// PreBootBroadcaster 的 sendNext 方法中会发送 ACTION_PRE_BOOT_COMPLETED!
new PreBootBroadcaster(mService, userId, null, quiet) {
public void onFinished() {
// 该方法会发送 ACTION_BOOT_COMPLETED 广播!
finishUserUnlockedCompleted(uss);
}
}.sendNext();
} else {
// 该方法会发送 ACTION_BOOT_COMPLETED 广播!
finishUserUnlockedCompleted(uss);
}
}
}
}
- ACTION_BOOT_COMPLETED
ACTION_PRE_BOOT_COMPLETED
广播是最后发送的,也就是我们说的开机广播,发送的代码在 finishUserUnlockedCompleted
方法中!
4 总结
到这里,AMS
的启动过程就分析完了!
[1]: