(PMS),顾名思义,其作用就是对我们的apk安装包进行管理服务,作为Android在java层的服务之一,其与所有其他的服务一样都是由SystemServer所启动的。
package com.android.server;
public final class SystemServer {
}
#SystemServer
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
//检查工厂测试模式
mFactoryTestMode = FactoryTest.getMode();
// Remember if it's runtime restart(when sys.boot_completed is already set) or reboot
//请记住,如果它是运行时重启(当sys.boot_completed已经设置)或重启
//在开机广播发送的流程中,会向系统写入sys.boot_completed,我们依据它可以得出当前系统是否已开机加载结束,这对一些系统服务或者app判断应用状态很有效。
mRuntimeRestart = "1".equals(SystemProperties.get("sys.boot_completed"));
}
#SystemServer
private void run() {
try {
traceBeginAndSlog("InitBeforeStartServices");
// If a device's clock is before 1970 (before 0), a lot of
// APIs crash dealing with negative numbers, notably
// java.io.File#setLastModified, so instead we fake it and
// hope that time from cell towers or NTP fixes it shortly.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
//
// Default the timezone property to GMT if not set.
//
String timezoneProperty = SystemProperties.get("persist.sys.timezone");
if (timezoneProperty == null || timezoneProperty.isEmpty()) {
Slog.w(TAG, "Timezone not set; setting to GMT.");
SystemProperties.set("persist.sys.timezone", "GMT");
}
// If the system has "persist.sys.language" and friends set, replace them with
// "persist.sys.locale". Note that the default locale at this point is calculated
// using the "-Duser.locale" command line flag. That flag is usually populated by
// AndroidRuntime using the same set of system properties, but only the system_server
// and system apps are allowed to set them.
//
// NOTE: Most changes made here will need an equivalent change to
// core/jni/AndroidRuntime.cpp
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// The system server should never make non-oneway calls
Binder.setWarnOnBlocking(true);
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
int uptimeMillis = (int) SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis);
}
/// M: BOOTPROF
sMtkSystemServerIns.addBootEvent("Android:SysServerInit_START");
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
// property so that it is in sync. We can | xq oqi't do this in
// libnativehelper's JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Mmmmmm... more memory!
VMRuntime.getRuntime().clearGrowthLimit();
// The system server has to run all of the time, so it needs to be
// as efficient as possible with its memory usage.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
// Some devices rely on runtime fingerprint generation, so make sure
// we've defined it before booting further.
Build.ensureFingerprintProperty();
// Within the system server, it is an error to access Environment paths without
// explicitly specifying a user.
Environment.setUserRequired(true);
// Within the system server, any incoming Bundles should be defused
// to avoid throwing BadParcelableException.
BaseBundle.setShouldDefuse(true);
// Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);
// Increase the number of binder threads in system_server
BinderInternal.setMaxThreads(sMaxBinderThreads);
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
//准备消息循环
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool.get();
} finally {
traceEnd(); // InitBeforeStartServices
}
/// M: Set paramters to mtkSystemserver.
sMtkSystemServerIns.setPrameters(BOOT_TIMINGS_TRACE_LOG, mSystemServiceManager,
mSystemContext);
// Start services.
try {
traceBeginAndSlog("StartServices");
startBootstrapServices();
/// M: For mtk systemserver
sMtkSystemServerIns.startMtkBootstrapServices();
startCoreServices();
/// M: for mtk other service.
sMtkSystemServerIns.startMtkCoreServices();
startOtherServices();
SystemServerInitThreadPool.shutdown();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
traceEnd();
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
/// M: open wtf when load is user or userdebug.
if (!"eng".equals(Build.TYPE) && !mRuntimeRestart && !isFirstBootOrUpgrade()) {
int uptimeMillis = (int) SystemClock.elapsedRealtime();
MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis);
final int MAX_UPTIME_MILLIS = 60 * 1000;
if (uptimeMillis > MAX_UPTIME_MILLIS) {
Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
/// M: BOOTPROF
sMtkSystemServerIns.addBootEvent("Android:SysServerInit_END");
// Loop forever.
//进入消息循环
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
private PackageManagerService mPackageManagerService;
/**
* Starts the small tangle of critical services that are needed to get
* the system off the ground. These services have complex mutual dependencies
* which is why we initialize them all in one place here. Unless your service
* is also entwined in these dependencies, it should be initialized in one of
* the other functions.
*/
private void startBootstrapServices() {
... ...
//通过PackageManagerService的静态main方法得到PackageManagerService 对象
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
... ...
}
在startBootstrapServices()方法中,通过PackageManagerService 的静态方法main方法得到一个PackageManagerService 对象。
package com.android.server.pm;
public class PackageManagerService extends IPackageManager.Stub
implements PackageSender {
}
#PackageManagerService
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
// Self-check for initial settings.
PackageManagerServiceCompilerMapping.checkProperties();
//构造一个包管理器对象
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
//将该包管理服务添加至 ServiceManager
ServiceManager.addService("package", m);
final PackageManagerNative pmn = m.new PackageManagerNative();
ServiceManager.addService("package_native", pmn);
return m;
}
ServiceManager是Binder进程间通信机制的守护进程,其目的非常简单,就是管理Android系统里的Binder对象。重点观察PackageManagerServer的构造过程。
SystemConfig systemConfig = SystemConfig.getInstance();
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
... ...
//向事件日志写入事件,标识PackageManagerServer 启动
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
SystemClock.uptimeMillis());
//SDK版本检查
if (mSdkVersion <= 0) {
Slog.w(TAG, "**** ro.build.version.sdk not set!");
}
//上下文环境对象
mContext = context;
//开机模式是否是工厂模式
mFactoryTest = factoryTest;
//是否仅启动内核
mOnlyCore = onlyCore;
//构造DisplayMetrics对象以便获取尺寸数据
mMetrics = new DisplayMetrics();
//构造Settings对象存储系统运行时的设置信息
mSettings = new Settings(mPackages);
//添加一些用户uid,首先是Setting的相关信息处理
/** * name = "android.uid.system", * uid = Process.SYSTEM_UID(1000), * pkgFlags = ApplicationInfo.FLAG_SYSTEM ,表示该应用安装在系统进程中,属于系统应用 * ,pkgPrivateFlags = ApplicationInfo.PRIVATE_FLAG_PRIVILEGED */
mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
//判断是否在不同进程
String separateProcesses = SystemProperties.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
if ("*".equals(separateProcesses)) {
mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
mSeparateProcesses = null;
Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
} else {
mDefParseFlags = 0;
mSeparateProcesses = separateProcesses.split(",");
Slog.w(TAG, "Running with debug.separate_processes: "
+ separateProcesses);
}
} else {
mDefParseFlags = 0;
mSeparateProcesses = null;
}
//Installer由SystemServer构造,这里通过该对象负责与底层通信,进行具体的安装卸载等操作。
mInstaller = installer;
synchronized (mInstallLock) {
// writer
synchronized (mPackages) {
//启动消息处理线程
mHandlerThread = new ServiceThread(TAG,
Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
mHandlerThread.start();
//通过消息处理线程的Looper对象构建一个处理消息的Handler对象
mHandler = new PackageHandler(mHandlerThread.getLooper());
//使用看门狗监测当前消息处理线程
Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
//获取当前的Data目录
File dataDir = Environment.getDataDirectory();
//具体对应的是/data/app目录
mAppInstallDir = new File(dataDir, "app");
//具体对应的是/data/app-lib目录
mAppLib32InstallDir = new File(dataDir, "app-lib");
//具体对应的是/data/app-asec目录
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
//具体对应的是/data/app-private目录
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
//构造UserManagerService 对象
sUserManager = new UserManagerService(context, this,
new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
//获取权限信息
//解析XML文件获取到系统所有权限配置信息。
//SystemConfig这个类扫描 /etc/sysconfig 和 /etc/permissions/目录,
ArrayMap<String, SystemConfig.PermissionEntry> permConfig
= systemConfig.getPermissions();
//保存jar包,依赖库
ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
//尝试读取并解析mac_permissions.xml文件
mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
//判断是否有自定义解析界面(自定义解析界面有什么用?)
String customResolverActivity = Resources.getSystem().getString(
R.string.config_customResolverActivity);
//标识扫描开始的时间戳
long startTime = SystemClock.uptimeMillis();
//将事件写入事件日志
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START, startTime);
//设置扫描模式
//
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
//获取SDK版本
final VersionInfo ver = mSettings.getInternalVersion();
//调用scanDirTracedLI 方法扫描/system/priv-app目录下的apk文件进行安装扫描模式为非优化模式
// Collected privileged system packages.
final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
scanDirTracedLI(privilegedAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR
| PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
//同上,针对的是/system/app目录
// Collect ordinary system packages.
final File systemAppDir = new File(Environment.getRootDirectory(), "app");
scanDirTracedLI(systemAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
//同上,针对的是/vender/app目录
// Collect all vendor packages.
File vendorAppDir = new File("/vendor/app");
try {
vendorAppDir = vendorAppDir.getCanonicalFile();
} catch (IOException e) {
// failed to look up canonical path, continue with original one
}
scanDirTracedLI(vendorAppDir, mDefParseFlags
| PackageParser.PARSE_IS_SYSTEM
| PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
// Prune any system packages that no longer exist.
//构造一个String类型的ArrayList列表,存储不存在的系统package路径
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
// Stub packages must either be replaced with full versions in the /data
// partition or be disabled.
final List<String> stubSystemApps = new ArrayList<>();
if (!mOnlyCore) {
// do this first before mucking with mPackages for the "expecting better" case
//遍历成员变量mPackages
final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
}
//更新相关信息,并给需要使用使用权限的apk分配相应权限
updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
// If this is the first boot or an update from pre-M, and it is a normal
// boot, then we need to initialize the default preferred apps across
// all defined users.
//如果本次启动是第一次正常启动,那么同时还需要初始化一些默认首选App
if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
for (UserInfo user : sUserManager.getUsers(true)) {
mSettings.applyDefaultPreferredAppsLPw(this, user.id);
applyFactoryDefaultBrowserLPw(user.id);
primeDomainVerificationsLPw(user.id);
}
}
//将信息写到相关文件中
mSettings.writeLPr();
//通知GC回收资源
Runtime.getRuntime().gc();
}
}
}
#Settings构造函数,主要是一些文件初始化工作
Settings(Object lock) {
// Environment.getDataDirectory() : /data
this(Environment.getDataDirectory(), lock);
}
Settings(File dataDir, Object lock) {
mLock = lock;
mRuntimePermissionsPersistence = new RuntimePermissionPersistence(mLock);
mSystemDir = new File(dataDir, "system");// /data/system
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
// /data/system/packages.xml
mSettingsFilename = new File(mSystemDir, "packages.xml");
// /data/system/packages-backup.xml
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
// /data/system/packages.list
mPackageListFilename = new File(mSystemDir, "packages.list");
FileUtils.setPermissions(mPackageListFilename, 0640, SYSTEM_UID, PACKAGE_INFO_GID);
final File kernelDir = new File("/config/sdcardfs");
mKernelMappingFilename = kernelDir.exists() ? kernelDir : null;
// Deprecated: Needed for migration
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
Settings.addSharedUserLPw()
#Settings
SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
// mSharedUsers:ArrayMap<String, SharedUserSetting> 是一个Map,key值为uid字符窜描述,value为SharedUserSetting
SharedUserSetting s = mSharedUsers.get(name);
if (s != null) {// 从Map中直接取出来
if (s.userId == uid) {
return s;
}
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared user, keeping first: " + name);
return null;
}
// Map中没有,生成一个
s = new SharedUserSetting(name, pkgFlags, pkgPrivateFlags);
s.userId = uid;
if (addUserIdLPw(uid, s, name)) {
mSharedUsers.put(name, s);
return s;
}
return null;
}
#Settings
private boolean addUserIdLPw(int uid, Object obj, Object name) {
if (uid > Process.LAST_APPLICATION_UID) { // uid > 19999
return false;
}
if (uid >= Process.FIRST_APPLICATION_UID) { // uid >= 10000 && uid <= 19999-->普通APK所在的进程UID
int N = mUserIds.size();
final int index = uid - Process.FIRST_APPLICATION_UID;
while (index >= N) {
mUserIds.add(null);
N++;
}
if (mUserIds.get(index) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate user id: " + uid
+ " name=" + name);
return false;
}
mUserIds.set(index, obj);
} else { // uid < 10000 && uid > 0-->系统APK所在的进程UID
if (mOtherUserIds.get(uid) != null) {
PackageManagerService.reportSettingsProblem(Log.ERROR,
"Adding duplicate shared id: " + uid
+ " name=" + name);
return false;
}
mOtherUserIds.put(uid, obj);
}
return true;
}
整个PackageManagerService的构造过程很长,但是,逻辑并不复杂,条理也很清晰。总体来说,PackageManagerService的作用就如它名字所述的那样,主要用来管理应用程序包。
参考《Android源码设计模式》