Android框架层PackageManagerService构造方法中的两个synchronized
2013-11-16 21:53
453 查看
在此之前的一些操作基本上都是比较简单的,也没有做什么核心的事情。主要是在这两个synchronized中,开始时,启动一个名为PackageManager的消息线程,该线程是PackageManagerService的工作线程,mHandlerThread线程是一个带消息循环的工作线程,在定义该线程对象的时候就已经创建。
mHandlerThread.start();// 启动消息处理线程
对于对象mHandlerThreadfinal老早就创建好了
final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
Process.THREAD_PRIORITY_BACKGROUND);
同时为该消息线程创建了一个消息分发器PackageHandler对象,通过该handler对象可以往PackageManager线程发送消息,PackageManager线程通过消息循环处理发送进来的消息,消息处理过程如下:
class PackageHandler extends Handler {。。。。}
在这里这些消息并非是在PackageHandler中处理的,而是通过连接服务MCS,通过MCS服务间接的完成消息处理的。(见PackageHandler代码,其中有启动连接服务的方法connectToService,disconnectService。
======================================================================================
之后就是,,
// 获取路径
File dataDir = Environment.getDataDirectory();// // dataDir
// =/data/
mAppDataDir = new File(dataDir, "data");// 创建目录 mAppDataDir =
// /data/data
mUserAppDataDir = new File(dataDir, "user");// mUserAppDataDir =
// /data/user
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");// mDrmAppPrivateInstallDir=
// UserManager类似与动态数据库
mUserManager = new UserManager(mInstaller, mUserAppDataDir);
创建/data/目录,上面mUserManager = new UserManager(mInstaller, mUserAppDataDir);是初始化user信息,也即是构造UserManager。
UserManager(File dataDir, File baseUserPath) {
mUsersDir = new File(dataDir, USER_INFO_DIR);
mUsersDir.mkdirs();
mBaseUserPath = baseUserPath;
FileUtils.setPermissions(mUsersDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
readUserList();
}
public UserManager(Installer installer, File baseUserPath) {
this(Environment.getDataDirectory(), baseUserPath);
mInstaller = installer;
}
下面的构造调用了上面的,
private void readUserList() {
mUsers = new SparseArray<UserInfo>();
if (!mUserListFile.exists()) {
fallbackToSingleUser();
return;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(mUserListFile);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read user list");
fallbackToSingleUser();
return;
}
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
String id = parser.getAttributeValue(null, ATTR_ID);
UserInfo user = readUser(Integer.parseInt(id));
if (user != null) {
mUsers.put(user.id, user);
}
}
}
updateUserIds();
} catch (IOException ioe) {
fallbackToSingleUser();
} catch (XmlPullParserException pe) {
fallbackToSingleUser();
}
}
UserInfo user = readUser(Integer.parseInt(id));
if (user != null) {
mUsers.put(user.id, user);
}
这里都是解析xml文件,获取用户信息。。将获取到的UserInfo保存到UserManager中的mUsers中。
====================================================================
解析系统permission信息
void readPermissions() {
// Read permissions from .../etc/permission directory.
File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.w(TAG, "No directory " + libraryDir + ", skipping");
return;
}
if (!libraryDir.canRead()) {
Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
return;
}
// 循环读取etc/permissions目录下的XML文件
for (File f : libraryDir.listFiles()) {
// 跳过platform.xml文件,最后读取该文件
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
continue;
}
if (!f.getPath().endsWith(".xml")) {
Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
continue;
}
if (!f.canRead()) {
Slog.w(TAG, "Permissions library file " + f + " cannot be read");
continue;
}
readPermissionsFromXml(f);
}
// Read permissions from .../etc/permissions/platform.xml last so it will take precedence
final File permFile = new File(Environment.getRootDirectory(),"etc/permissions/platform.xml");
readPermissionsFromXml(permFile);
}
函数readPermissionsFromXml使用PULL方式解析这些XML文件,下面分别介绍各个标签的解析过程。
feature标签用来描述设备应该支持的硬件特性。解析过程如下:
[java]
view plaincopyprint?
else if ("feature".equals(name)) {
//读取熟悉name的值
String fname = parser.getAttributeValue(null, "name");
if (fname == null) {
Slog.w(TAG, "<feature> without name at "+ parser.getPositionDescription());
} else {
//创建一个FeatureInfo对象
FeatureInfo fi = new FeatureInfo();
fi.name = fname;
//mAvailableFeatures是PackageManagerService的成员变量,以HashMap的方式保存硬件支持的特性
mAvailableFeatures.put(fname, fi);
}
XmlUtils.skipCurrentTag(parser);
continue;
}
library用于指定系统库,当应用程序运行时,系统会为进程加载一些必要库。该标签的解析过程如下:
[java]
view plaincopyprint?
else if ("library".equals(name)) {
//读取属性name的值
String lname = parser.getAttributeValue(null, "name");
//读取属性file的值
String lfile = parser.getAttributeValue(null, "file");
if (lname == null) {
Slog.w(TAG, "<library> without name at "+ parser.getPositionDescription());
} else if (lfile == null) {
Slog.w(TAG, "<library> without file at "+ parser.getPositionDescription());
} else {
//mSharedLibraries是PackageManagerService的成员变量,以HashMap的形式保存进程运行库
mSharedLibraries.put(lname, lfile);
}
XmlUtils.skipCurrentTag(parser);
continue;
}
其他的见代码。。。。
===============================================================================
读取package信息
/data/system/packages.xml文件用于记录系统中所安装的Package信息;/data/system/packages-backup.xml文件是/data/packages.xml文件的备份。在PackageManagerService扫描完目标文件夹后会创建该文件,当系统进行程序安装卸载时会更新该文件。
/data/system/packages-stopped.xml文件用于记录系统中强制停止运行的Package信息。/data/system/packages-stopped-backup.xml是/data/packages-stopped.xml文件的备份。在强制停止某个应用时,会将应用相关信息记录到该文件中。
/data/system/packages.list保存系统中存在的所有非系统自带的APK信息。
当系统第一次开机时,这些文件并不存在,而在以后的开机中,扫描到的这些XML文件是上一次运行过程中创建的。
[java]
view plaincopyprint?
boolean readLPw(List<UserInfo> users) {
FileInputStream str = null;
//如果/data/system/packages-backup.xml文件存在
if (mBackupSettingsFilename.exists()) {
try {
//读取/data/system/packages-backup.xml文件
str = new FileInputStream(mBackupSettingsFilename);
mReadMessages.append("Reading from backup settings file\n");
PackageManagerService.reportSettingsProblem(Log.INFO,"Need to read from backup settings file");
//当/data/system/packages.xml文件的备份文件存在时,删除packages.xml文件
if (mSettingsFilename.exists()) {
Slog.w(PackageManagerService.TAG, "Cleaning up settings file "+ mSettingsFilename);
mSettingsFilename.delete();
}
} catch (java.io.IOException e) {
// We'll try for the normal settings file.
}
}
mPendingPackages.clear();
mPastSignatures.clear();
try {
//如果/data/system/packages-backup.xml文件为空
if (str == null) {
//同时/data/system/packages.xml文件不存在
if (!mSettingsFilename.exists()) {
mReadMessages.append("No settings file found\n");
PackageManagerService.reportSettingsProblem(Log.INFO,
"No settings file; creating initial state");
//读取/etc/preferred-apps目录下的xml文件
readDefaultPreferredAppsLPw();
return false;
}
//如果packages.xml的备份文件为空,读取packages.xml文件内容
str = new FileInputStream(mSettingsFilename);
}
//解析文件内容
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
...
}
接下来检测并优化BOOTCLASSPATH环境变量指定的Java运行库及platform.xml中配置的Java库,同时优化/system/framework目录下的Jar包和apk文件,最后删除/data/dalvik-cache目录下的一些缓存文件。在init.rc中配置的BOOTCLASSPATH如下:
long startTime = SystemClock.uptimeMillis();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,startTime);
// 设置扫描模式
int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
if (mNoDexOpt) {
Slog.w(TAG, "Running ENG build: no pre-dexopt!");
scanMode |= SCAN_NO_DEX;
}
//保存库文件路径
final HashSet<String> libFiles = new HashSet<String>();
//mFrameworkDir = /framework/
mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
//mDalvikCacheDir = /data/dalvik-cache/
mDalvikCacheDir = new File(dataDir, "dalvik-cache");
boolean didDexOpt = false;
//通过属性的方式得到启动Java启动类库的路径,在init.rc中通过BOOTCLASSPATH环境变量的方式设置
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':');
for (int i=0; i<paths.length; i++) {
try {
//判断Jar包是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
//如果需要则添加到libFiles表中
libFiles.add(paths[i]);
//通过安装器请求installd服务进程执行dex优化
mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Boot class path not found: " + paths[i]);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
+ e.getMessage());
}
}
} else {
Slog.w(TAG, "No BOOTCLASSPATH found!");
}
//在前面解析platfor.xml时,将一些额外的类库路径保存到了mSharedLibraries变量中
if (mSharedLibraries.size() > 0) {
//循环变量mSharedLibraries变量
Iterator<String> libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
//判断Jar包是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
//如果需要则添加到libFiles表中
libFiles.add(lib);
//通过安装器进行dex优化
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ e.getMessage());
}
}
}
//将/system/frameworks/framework-res.apk添加到libFiles中
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
//列出/system/frameworks目录下的文件
String[] frameworkFiles = mFrameworkDir.list();
if (frameworkFiles != null) {
//遍历/system/frameworks目录下的文件
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(mFrameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
//判断libFiles中是否已经包含该文件,如果包含则跳过
if (libFiles.contains(path)) {
continue;
}
//跳过不是apk或jar文件
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
continue;
}
try {
//判断Jar包或apk是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(path)) {
//通过安装器进行dex优化
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Slog.w(TAG, "Exception reading jar: " + path, e);
}
}
}
//如果前面对某个文件做过优化,只要优化了,didDexOpt就被设置为true
if (didDexOpt) {
//遍历/data/dalvik-cache目录下的文件
String[] files = mDalvikCacheDir.list();
if (files != null) {
for (int i=0; i<files.length; i++) {
String fn = files[i];
//删除文件名以"data@app@"和"data@app-private@"开头的文件
if (fn.startsWith("data@app@")
|| fn.startsWith("data@app-private@")) {
Slog.i(TAG, "Pruning dalvik file: " + fn);
(new File(mDalvikCacheDir, fn)).delete();
}
}
}
}
接着扫描系统apk信息
[java]
view plaincopyprint?
mFlagInstall = false;
//创建文件夹监控对象,监视/system/framework目录
mFrameworkInstallObserver = new AppDirObserver(mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
//扫描/system/framework目录下的apk文件,扫描模式设置为非优化模式
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR,scanMode | SCAN_NO_DEX, 0);
//在工厂模式下,调用函数scanDirLIOnly只扫描特定的apk文件
if(engModeEnable){
//temp null
mVendorAppDir = null;
mDrmAppInstallObserver = null;
mSystemAppDir = null;
mAppInstallObserver = null;
mSystemInstallObserver = null;
mPreInstallObserver = null;
mVendorInstallObserver = null;
mAppInstallDir = null;
Slog.i(TAG, " begin scan the apps !");
scanDirLIOnly(PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
Slog.i(TAG, " end scan the apps !");
engModeEnable = false;
}else{//正常模式下
//创建文件夹监控对象,监视/system/app目录
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(
mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
mSystemInstallObserver.startWatching();
//扫描/system/app目录
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
//创建文件夹监控对象,监视/vendor/app目录
mVendorAppDir = new File("/vendor/app");
mVendorInstallObserver = new AppDirObserver(
mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
mVendorInstallObserver.startWatching();
//扫描/vendor/app目录
scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
mInstaller.moveFiles();
// Prune any system packages that no longer exist.
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
if (!mOnlyCore) {
//遍历Settings的成员变量mPackages
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
//不是系统app
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
//如果是系统app,同时已经被PackageManagerService扫描过了
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
//该apk包已不能使用
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
Slog.i(TAG, "Expecting better updatd system app for " + ps.name
+ "; removing system app");
//移除该apk包信息
removePackageLI(scannedPkg, true);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
String msg = "System package " + ps.name
+ " no longer exists; wiping its data";
reportSettingsProblem(Log.WARN, msg);
mInstaller.remove(ps.name, 0);
sUserManager.removePackageForAllUsers(ps.name);
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
//mAppInstallDir = /data/app/
mAppInstallDir = new File(dataDir, "app");
//查找未完成安装的apk包
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//清除未完成安装包
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
cleanupInstallFailedPackage(deletePkgsList.get(i));
}
//删除临时文件
deleteTempPackageFiles();
监控并扫描以下三个系统包安装目录:
/system/framework :该目录下的文件都是系统库
/system/app :该目录下是默认的系统应用
/vendor/app :该目录下是厂商定制的应用
最后扫描非系统apk信息
[java]
view plaincopyprint?
if (!mOnlyCore) {
//标识数据扫描开始 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,SystemClock.uptimeMillis());
//创建文件夹监控对象,监视/data/app/目录
mAppInstallObserver = new AppDirObserver(mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
mAppInstallObserver.startWatching();
//扫描/data/app/目录下的apk文件
scanDirLI(mAppInstallDir, 0, scanMode, 0);
//创建文件夹监控对象,监视/system/preloadapp/目录
mPreInstallObserver = new AppDirObserver(mPreInstallDir.getPath(), OBSERVER_EVENTS, false);
mPreInstallObserver.startWatching();
//扫描/system/preloadapp/目录下的apk文件
scanDirLI(mPreInstallDir, 0, scanMode, 0);
//创建文件夹监控对象,监视/data/app-private/目录
mDrmAppInstallObserver = new AppDirObserver(mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
//扫描/data/app-private/目录下的apk文件
scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,scanMode, 0);
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
* previously-updated app, remove them completely.
* Otherwise, just revoke their system-level permissions.
*/
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName+ " no longer exists; wiping its data";
mInstaller.remove(deletedAppName, 0);
sUserManager.removePackageForAllUsers(deletedAppName);
} else {
msg = "Updated system app + " + deletedAppName+ " no longer present; removing system privileges for "+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
reportSettingsProblem(Log.WARN, msg);
}
} else {
mPreInstallObserver = null;
mAppInstallObserver = null;
mDrmAppInstallObserver = null;
}
监控并扫描以下三个数据目录:
/data/app/
/system/preloadapp/
/data/app-private/
最后进入结尾阶段,将扫描到的信息保存到文件中。
[java]
view plaincopyprint?
mFlagInstall = true;
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis());
final boolean regrantPermissions = mSettings.mInternalSdkPlatform != mSdkVersion;
mSettings.mInternalSdkPlatform = mSdkVersion;
updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL | (regrantPermissions
? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL): 0));
ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
removed.add(pa);
}
}
for (int i=0; i<removed.size(); i++) {
PreferredActivity pa = removed.get(i);
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
mSettings.mPreferredActivities.removeFilter(pa);
}
// can downgrade to reader
mSettings.writeLPr();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,SystemClock.uptimeMillis());
Runtime.getRuntime().gc();
mRequiredVerifierPackage = getRequiredVerifierLPr();
至此,PackageManagerService就构造完成了,构造过程认为繁重,Apk文件扫描解析耗费比较长的时间,这是导致开机速度慢的原因。
mHandlerThread.start();// 启动消息处理线程
对于对象mHandlerThreadfinal老早就创建好了
final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
Process.THREAD_PRIORITY_BACKGROUND);
同时为该消息线程创建了一个消息分发器PackageHandler对象,通过该handler对象可以往PackageManager线程发送消息,PackageManager线程通过消息循环处理发送进来的消息,消息处理过程如下:
class PackageHandler extends Handler {。。。。}
在这里这些消息并非是在PackageHandler中处理的,而是通过连接服务MCS,通过MCS服务间接的完成消息处理的。(见PackageHandler代码,其中有启动连接服务的方法connectToService,disconnectService。
======================================================================================
之后就是,,
// 获取路径
File dataDir = Environment.getDataDirectory();// // dataDir
// =/data/
mAppDataDir = new File(dataDir, "data");// 创建目录 mAppDataDir =
// /data/data
mUserAppDataDir = new File(dataDir, "user");// mUserAppDataDir =
// /data/user
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");// mDrmAppPrivateInstallDir=
// UserManager类似与动态数据库
mUserManager = new UserManager(mInstaller, mUserAppDataDir);
创建/data/目录,上面mUserManager = new UserManager(mInstaller, mUserAppDataDir);是初始化user信息,也即是构造UserManager。
UserManager(File dataDir, File baseUserPath) {
mUsersDir = new File(dataDir, USER_INFO_DIR);
mUsersDir.mkdirs();
mBaseUserPath = baseUserPath;
FileUtils.setPermissions(mUsersDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mUserListFile = new File(mUsersDir, USER_LIST_FILENAME);
readUserList();
}
public UserManager(Installer installer, File baseUserPath) {
this(Environment.getDataDirectory(), baseUserPath);
mInstaller = installer;
}
下面的构造调用了上面的,
private void readUserList() {
mUsers = new SparseArray<UserInfo>();
if (!mUserListFile.exists()) {
fallbackToSingleUser();
return;
}
FileInputStream fis = null;
try {
fis = new FileInputStream(mUserListFile);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(fis, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
if (type != XmlPullParser.START_TAG) {
Slog.e(LOG_TAG, "Unable to read user list");
fallbackToSingleUser();
return;
}
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG && parser.getName().equals(TAG_USER)) {
String id = parser.getAttributeValue(null, ATTR_ID);
UserInfo user = readUser(Integer.parseInt(id));
if (user != null) {
mUsers.put(user.id, user);
}
}
}
updateUserIds();
} catch (IOException ioe) {
fallbackToSingleUser();
} catch (XmlPullParserException pe) {
fallbackToSingleUser();
}
}
UserInfo user = readUser(Integer.parseInt(id));
if (user != null) {
mUsers.put(user.id, user);
}
这里都是解析xml文件,获取用户信息。。将获取到的UserInfo保存到UserManager中的mUsers中。
====================================================================
解析系统permission信息
void readPermissions() {
// Read permissions from .../etc/permission directory.
File libraryDir = new File(Environment.getRootDirectory(), "etc/permissions");
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.w(TAG, "No directory " + libraryDir + ", skipping");
return;
}
if (!libraryDir.canRead()) {
Slog.w(TAG, "Directory " + libraryDir + " cannot be read");
return;
}
// 循环读取etc/permissions目录下的XML文件
for (File f : libraryDir.listFiles()) {
// 跳过platform.xml文件,最后读取该文件
if (f.getPath().endsWith("etc/permissions/platform.xml")) {
continue;
}
if (!f.getPath().endsWith(".xml")) {
Slog.i(TAG, "Non-xml file " + f + " in " + libraryDir + " directory, ignoring");
continue;
}
if (!f.canRead()) {
Slog.w(TAG, "Permissions library file " + f + " cannot be read");
continue;
}
readPermissionsFromXml(f);
}
// Read permissions from .../etc/permissions/platform.xml last so it will take precedence
final File permFile = new File(Environment.getRootDirectory(),"etc/permissions/platform.xml");
readPermissionsFromXml(permFile);
}
函数readPermissionsFromXml使用PULL方式解析这些XML文件,下面分别介绍各个标签的解析过程。
feature标签用来描述设备应该支持的硬件特性。解析过程如下:
[java]
view plaincopyprint?
else if ("feature".equals(name)) {
//读取熟悉name的值
String fname = parser.getAttributeValue(null, "name");
if (fname == null) {
Slog.w(TAG, "<feature> without name at "+ parser.getPositionDescription());
} else {
//创建一个FeatureInfo对象
FeatureInfo fi = new FeatureInfo();
fi.name = fname;
//mAvailableFeatures是PackageManagerService的成员变量,以HashMap的方式保存硬件支持的特性
mAvailableFeatures.put(fname, fi);
}
XmlUtils.skipCurrentTag(parser);
continue;
}
library用于指定系统库,当应用程序运行时,系统会为进程加载一些必要库。该标签的解析过程如下:
[java]
view plaincopyprint?
else if ("library".equals(name)) {
//读取属性name的值
String lname = parser.getAttributeValue(null, "name");
//读取属性file的值
String lfile = parser.getAttributeValue(null, "file");
if (lname == null) {
Slog.w(TAG, "<library> without name at "+ parser.getPositionDescription());
} else if (lfile == null) {
Slog.w(TAG, "<library> without file at "+ parser.getPositionDescription());
} else {
//mSharedLibraries是PackageManagerService的成员变量,以HashMap的形式保存进程运行库
mSharedLibraries.put(lname, lfile);
}
XmlUtils.skipCurrentTag(parser);
continue;
}
其他的见代码。。。。
===============================================================================
读取package信息
/data/system/packages.xml文件用于记录系统中所安装的Package信息;/data/system/packages-backup.xml文件是/data/packages.xml文件的备份。在PackageManagerService扫描完目标文件夹后会创建该文件,当系统进行程序安装卸载时会更新该文件。
/data/system/packages-stopped.xml文件用于记录系统中强制停止运行的Package信息。/data/system/packages-stopped-backup.xml是/data/packages-stopped.xml文件的备份。在强制停止某个应用时,会将应用相关信息记录到该文件中。
/data/system/packages.list保存系统中存在的所有非系统自带的APK信息。
当系统第一次开机时,这些文件并不存在,而在以后的开机中,扫描到的这些XML文件是上一次运行过程中创建的。
[java]
view plaincopyprint?
boolean readLPw(List<UserInfo> users) {
FileInputStream str = null;
//如果/data/system/packages-backup.xml文件存在
if (mBackupSettingsFilename.exists()) {
try {
//读取/data/system/packages-backup.xml文件
str = new FileInputStream(mBackupSettingsFilename);
mReadMessages.append("Reading from backup settings file\n");
PackageManagerService.reportSettingsProblem(Log.INFO,"Need to read from backup settings file");
//当/data/system/packages.xml文件的备份文件存在时,删除packages.xml文件
if (mSettingsFilename.exists()) {
Slog.w(PackageManagerService.TAG, "Cleaning up settings file "+ mSettingsFilename);
mSettingsFilename.delete();
}
} catch (java.io.IOException e) {
// We'll try for the normal settings file.
}
}
mPendingPackages.clear();
mPastSignatures.clear();
try {
//如果/data/system/packages-backup.xml文件为空
if (str == null) {
//同时/data/system/packages.xml文件不存在
if (!mSettingsFilename.exists()) {
mReadMessages.append("No settings file found\n");
PackageManagerService.reportSettingsProblem(Log.INFO,
"No settings file; creating initial state");
//读取/etc/preferred-apps目录下的xml文件
readDefaultPreferredAppsLPw();
return false;
}
//如果packages.xml的备份文件为空,读取packages.xml文件内容
str = new FileInputStream(mSettingsFilename);
}
//解析文件内容
XmlPullParser parser = Xml.newPullParser();
parser.setInput(str, null);
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG
&& type != XmlPullParser.END_DOCUMENT) {
;
}
...
}
接下来检测并优化BOOTCLASSPATH环境变量指定的Java运行库及platform.xml中配置的Java库,同时优化/system/framework目录下的Jar包和apk文件,最后删除/data/dalvik-cache目录下的一些缓存文件。在init.rc中配置的BOOTCLASSPATH如下:
long startTime = SystemClock.uptimeMillis();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,startTime);
// 设置扫描模式
int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING;
if (mNoDexOpt) {
Slog.w(TAG, "Running ENG build: no pre-dexopt!");
scanMode |= SCAN_NO_DEX;
}
//保存库文件路径
final HashSet<String> libFiles = new HashSet<String>();
//mFrameworkDir = /framework/
mFrameworkDir = new File(Environment.getRootDirectory(), "framework");
//mDalvikCacheDir = /data/dalvik-cache/
mDalvikCacheDir = new File(dataDir, "dalvik-cache");
boolean didDexOpt = false;
//通过属性的方式得到启动Java启动类库的路径,在init.rc中通过BOOTCLASSPATH环境变量的方式设置
String bootClassPath = System.getProperty("java.boot.class.path");
if (bootClassPath != null) {
String[] paths = splitString(bootClassPath, ':');
for (int i=0; i<paths.length; i++) {
try {
//判断Jar包是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) {
//如果需要则添加到libFiles表中
libFiles.add(paths[i]);
//通过安装器请求installd服务进程执行dex优化
mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Boot class path not found: " + paths[i]);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? "
+ e.getMessage());
}
}
} else {
Slog.w(TAG, "No BOOTCLASSPATH found!");
}
//在前面解析platfor.xml时,将一些额外的类库路径保存到了mSharedLibraries变量中
if (mSharedLibraries.size() > 0) {
//循环变量mSharedLibraries变量
Iterator<String> libs = mSharedLibraries.values().iterator();
while (libs.hasNext()) {
String lib = libs.next();
try {
//判断Jar包是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(lib)) {
//如果需要则添加到libFiles表中
libFiles.add(lib);
//通过安装器进行dex优化
mInstaller.dexopt(lib, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib);
} catch (IOException e) {
Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? "
+ e.getMessage());
}
}
}
//将/system/frameworks/framework-res.apk添加到libFiles中
libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk");
//列出/system/frameworks目录下的文件
String[] frameworkFiles = mFrameworkDir.list();
if (frameworkFiles != null) {
//遍历/system/frameworks目录下的文件
for (int i=0; i<frameworkFiles.length; i++) {
File libPath = new File(mFrameworkDir, frameworkFiles[i]);
String path = libPath.getPath();
//判断libFiles中是否已经包含该文件,如果包含则跳过
if (libFiles.contains(path)) {
continue;
}
//跳过不是apk或jar文件
if (!path.endsWith(".apk") && !path.endsWith(".jar")) {
continue;
}
try {
//判断Jar包或apk是否需要dex优化
if (dalvik.system.DexFile.isDexOptNeeded(path)) {
//通过安装器进行dex优化
mInstaller.dexopt(path, Process.SYSTEM_UID, true);
didDexOpt = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
} catch (IOException e) {
Slog.w(TAG, "Exception reading jar: " + path, e);
}
}
}
//如果前面对某个文件做过优化,只要优化了,didDexOpt就被设置为true
if (didDexOpt) {
//遍历/data/dalvik-cache目录下的文件
String[] files = mDalvikCacheDir.list();
if (files != null) {
for (int i=0; i<files.length; i++) {
String fn = files[i];
//删除文件名以"data@app@"和"data@app-private@"开头的文件
if (fn.startsWith("data@app@")
|| fn.startsWith("data@app-private@")) {
Slog.i(TAG, "Pruning dalvik file: " + fn);
(new File(mDalvikCacheDir, fn)).delete();
}
}
}
}
long startTime = SystemClock.uptimeMillis(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,startTime); // 设置扫描模式 int scanMode = SCAN_MONITOR | SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; if (mNoDexOpt) { Slog.w(TAG, "Running ENG build: no pre-dexopt!"); scanMode |= SCAN_NO_DEX; } //保存库文件路径 final HashSet<String> libFiles = new HashSet<String>(); //mFrameworkDir = /framework/ mFrameworkDir = new File(Environment.getRootDirectory(), "framework"); //mDalvikCacheDir = /data/dalvik-cache/ mDalvikCacheDir = new File(dataDir, "dalvik-cache"); boolean didDexOpt = false; //通过属性的方式得到启动Java启动类库的路径,在init.rc中通过BOOTCLASSPATH环境变量的方式设置 String bootClassPath = System.getProperty("java.boot.class.path"); if (bootClassPath != null) { String[] paths = splitString(bootClassPath, ':'); for (int i=0; i<paths.length; i++) { try { //判断Jar包是否需要dex优化 if (dalvik.system.DexFile.isDexOptNeeded(paths[i])) { //如果需要则添加到libFiles表中 libFiles.add(paths[i]); //通过安装器请求installd服务进程执行dex优化 mInstaller.dexopt(paths[i], Process.SYSTEM_UID, true); didDexOpt = true; } } catch (FileNotFoundException e) { Slog.w(TAG, "Boot class path not found: " + paths[i]); } catch (IOException e) { Slog.w(TAG, "Cannot dexopt " + paths[i] + "; is it an APK or JAR? " + e.getMessage()); } } } else { Slog.w(TAG, "No BOOTCLASSPATH found!"); } //在前面解析platfor.xml时,将一些额外的类库路径保存到了mSharedLibraries变量中 if (mSharedLibraries.size() > 0) { //循环变量mSharedLibraries变量 Iterator<String> libs = mSharedLibraries.values().iterator(); while (libs.hasNext()) { String lib = libs.next(); try { //判断Jar包是否需要dex优化 if (dalvik.system.DexFile.isDexOptNeeded(lib)) { //如果需要则添加到libFiles表中 libFiles.add(lib); //通过安装器进行dex优化 mInstaller.dexopt(lib, Process.SYSTEM_UID, true); didDexOpt = true; } } catch (FileNotFoundException e) { Slog.w(TAG, "Library not found: " + lib); } catch (IOException e) { Slog.w(TAG, "Cannot dexopt " + lib + "; is it an APK or JAR? " + e.getMessage()); } } } //将/system/frameworks/framework-res.apk添加到libFiles中 libFiles.add(mFrameworkDir.getPath() + "/framework-res.apk"); //列出/system/frameworks目录下的文件 String[] frameworkFiles = mFrameworkDir.list(); if (frameworkFiles != null) { //遍历/system/frameworks目录下的文件 for (int i=0; i<frameworkFiles.length; i++) { File libPath = new File(mFrameworkDir, frameworkFiles[i]); String path = libPath.getPath(); //判断libFiles中是否已经包含该文件,如果包含则跳过 if (libFiles.contains(path)) { continue; } //跳过不是apk或jar文件 if (!path.endsWith(".apk") && !path.endsWith(".jar")) { continue; } try { //判断Jar包或apk是否需要dex优化 if (dalvik.system.DexFile.isDexOptNeeded(path)) { //通过安装器进行dex优化 mInstaller.dexopt(path, Process.SYSTEM_UID, true); didDexOpt = true; } } catch (FileNotFoundException e) { Slog.w(TAG, "Jar not found: " + path); } catch (IOException e) { Slog.w(TAG, "Exception reading jar: " + path, e); } } } //如果前面对某个文件做过优化,只要优化了,didDexOpt就被设置为true if (didDexOpt) { //遍历/data/dalvik-cache目录下的文件 String[] files = mDalvikCacheDir.list(); if (files != null) { for (int i=0; i<files.length; i++) { String fn = files[i]; //删除文件名以"data@app@"和"data@app-private@"开头的文件 if (fn.startsWith("data@app@") || fn.startsWith("data@app-private@")) { Slog.i(TAG, "Pruning dalvik file: " + fn); (new File(mDalvikCacheDir, fn)).delete(); } } } }
接着扫描系统apk信息
[java]
view plaincopyprint?
mFlagInstall = false;
//创建文件夹监控对象,监视/system/framework目录
mFrameworkInstallObserver = new AppDirObserver(mFrameworkDir.getPath(), OBSERVER_EVENTS, true);
mFrameworkInstallObserver.startWatching();
//扫描/system/framework目录下的apk文件,扫描模式设置为非优化模式
scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR,scanMode | SCAN_NO_DEX, 0);
//在工厂模式下,调用函数scanDirLIOnly只扫描特定的apk文件
if(engModeEnable){
//temp null
mVendorAppDir = null;
mDrmAppInstallObserver = null;
mSystemAppDir = null;
mAppInstallObserver = null;
mSystemInstallObserver = null;
mPreInstallObserver = null;
mVendorInstallObserver = null;
mAppInstallDir = null;
Slog.i(TAG, " begin scan the apps !");
scanDirLIOnly(PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
Slog.i(TAG, " end scan the apps !");
engModeEnable = false;
}else{//正常模式下
//创建文件夹监控对象,监视/system/app目录
mSystemAppDir = new File(Environment.getRootDirectory(), "app");
mSystemInstallObserver = new AppDirObserver(
mSystemAppDir.getPath(), OBSERVER_EVENTS, true);
mSystemInstallObserver.startWatching();
//扫描/system/app目录
scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
//创建文件夹监控对象,监视/vendor/app目录
mVendorAppDir = new File("/vendor/app");
mVendorInstallObserver = new AppDirObserver(
mVendorAppDir.getPath(), OBSERVER_EVENTS, true);
mVendorInstallObserver.startWatching();
//扫描/vendor/app目录
scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);
if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands");
mInstaller.moveFiles();
// Prune any system packages that no longer exist.
final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
if (!mOnlyCore) {
//遍历Settings的成员变量mPackages
Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
while (psit.hasNext()) {
PackageSetting ps = psit.next();
//不是系统app
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
//如果是系统app,同时已经被PackageManagerService扫描过了
final PackageParser.Package scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
//该apk包已不能使用
if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
Slog.i(TAG, "Expecting better updatd system app for " + ps.name
+ "; removing system app");
//移除该apk包信息
removePackageLI(scannedPkg, true);
}
continue;
}
if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
psit.remove();
String msg = "System package " + ps.name
+ " no longer exists; wiping its data";
reportSettingsProblem(Log.WARN, msg);
mInstaller.remove(ps.name, 0);
sUserManager.removePackageForAllUsers(ps.name);
} else {
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
possiblyDeletedUpdatedSystemApps.add(ps.name);
}
}
}
}
//mAppInstallDir = /data/app/
mAppInstallDir = new File(dataDir, "app");
//查找未完成安装的apk包
ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
//清除未完成安装包
for(int i = 0; i < deletePkgsList.size(); i++) {
//clean up here
cleanupInstallFailedPackage(deletePkgsList.get(i));
}
//删除临时文件
deleteTempPackageFiles();
mFlagInstall = false; //创建文件夹监控对象,监视/system/framework目录 mFrameworkInstallObserver = new AppDirObserver(mFrameworkDir.getPath(), OBSERVER_EVENTS, true); mFrameworkInstallObserver.startWatching(); //扫描/system/framework目录下的apk文件,扫描模式设置为非优化模式 scanDirLI(mFrameworkDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR,scanMode | SCAN_NO_DEX, 0); //在工厂模式下,调用函数scanDirLIOnly只扫描特定的apk文件 if(engModeEnable){ //temp null mVendorAppDir = null; mDrmAppInstallObserver = null; mSystemAppDir = null; mAppInstallObserver = null; mSystemInstallObserver = null; mPreInstallObserver = null; mVendorInstallObserver = null; mAppInstallDir = null; Slog.i(TAG, " begin scan the apps !"); scanDirLIOnly(PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); Slog.i(TAG, " end scan the apps !"); engModeEnable = false; }else{//正常模式下 //创建文件夹监控对象,监视/system/app目录 mSystemAppDir = new File(Environment.getRootDirectory(), "app"); mSystemInstallObserver = new AppDirObserver( mSystemAppDir.getPath(), OBSERVER_EVENTS, true); mSystemInstallObserver.startWatching(); //扫描/system/app目录 scanDirLI(mSystemAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); //创建文件夹监控对象,监视/vendor/app目录 mVendorAppDir = new File("/vendor/app"); mVendorInstallObserver = new AppDirObserver( mVendorAppDir.getPath(), OBSERVER_EVENTS, true); mVendorInstallObserver.startWatching(); //扫描/vendor/app目录 scanDirLI(mVendorAppDir, PackageParser.PARSE_IS_SYSTEM| PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0); if (DEBUG_UPGRADE) Log.v(TAG, "Running installd update commands"); mInstaller.moveFiles(); // Prune any system packages that no longer exist. final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>(); if (!mOnlyCore) { //遍历Settings的成员变量mPackages Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator(); while (psit.hasNext()) { PackageSetting ps = psit.next(); //不是系统app if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) { continue; } //如果是系统app,同时已经被PackageManagerService扫描过了 final PackageParser.Package scannedPkg = mPackages.get(ps.name); if (scannedPkg != null) { //该apk包已不能使用 if (mSettings.isDisabledSystemPackageLPr(ps.name)) { Slog.i(TAG, "Expecting better updatd system app for " + ps.name + "; removing system app"); //移除该apk包信息 removePackageLI(scannedPkg, true); } continue; } if (!mSettings.isDisabledSystemPackageLPr(ps.name)) { psit.remove(); String msg = "System package " + ps.name + " no longer exists; wiping its data"; reportSettingsProblem(Log.WARN, msg); mInstaller.remove(ps.name, 0); sUserManager.removePackageForAllUsers(ps.name); } else { final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name); if (disabledPs.codePath == null || !disabledPs.codePath.exists()) { possiblyDeletedUpdatedSystemApps.add(ps.name); } } } } //mAppInstallDir = /data/app/ mAppInstallDir = new File(dataDir, "app"); //查找未完成安装的apk包 ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr(); //清除未完成安装包 for(int i = 0; i < deletePkgsList.size(); i++) { //clean up here cleanupInstallFailedPackage(deletePkgsList.get(i)); } //删除临时文件 deleteTempPackageFiles();
监控并扫描以下三个系统包安装目录:
/system/framework :该目录下的文件都是系统库
/system/app :该目录下是默认的系统应用
/vendor/app :该目录下是厂商定制的应用
最后扫描非系统apk信息
[java]
view plaincopyprint?
if (!mOnlyCore) {
//标识数据扫描开始 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,SystemClock.uptimeMillis());
//创建文件夹监控对象,监视/data/app/目录
mAppInstallObserver = new AppDirObserver(mAppInstallDir.getPath(), OBSERVER_EVENTS, false);
mAppInstallObserver.startWatching();
//扫描/data/app/目录下的apk文件
scanDirLI(mAppInstallDir, 0, scanMode, 0);
//创建文件夹监控对象,监视/system/preloadapp/目录
mPreInstallObserver = new AppDirObserver(mPreInstallDir.getPath(), OBSERVER_EVENTS, false);
mPreInstallObserver.startWatching();
//扫描/system/preloadapp/目录下的apk文件
scanDirLI(mPreInstallDir, 0, scanMode, 0);
//创建文件夹监控对象,监视/data/app-private/目录
mDrmAppInstallObserver = new AppDirObserver(mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false);
mDrmAppInstallObserver.startWatching();
//扫描/data/app-private/目录下的apk文件
scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,scanMode, 0);
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
* previously-updated app, remove them completely.
* Otherwise, just revoke their system-level permissions.
*/
for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
mSettings.removeDisabledSystemPackageLPw(deletedAppName);
String msg;
if (deletedPkg == null) {
msg = "Updated system package " + deletedAppName+ " no longer exists; wiping its data";
mInstaller.remove(deletedAppName, 0);
sUserManager.removePackageForAllUsers(deletedAppName);
} else {
msg = "Updated system app + " + deletedAppName+ " no longer present; removing system privileges for "+ deletedAppName;
deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
}
reportSettingsProblem(Log.WARN, msg);
}
} else {
mPreInstallObserver = null;
mAppInstallObserver = null;
mDrmAppInstallObserver = null;
}
if (!mOnlyCore) { //标识数据扫描开始 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,SystemClock.uptimeMillis()); //创建文件夹监控对象,监视/data/app/目录 mAppInstallObserver = new AppDirObserver(mAppInstallDir.getPath(), OBSERVER_EVENTS, false); mAppInstallObserver.startWatching(); //扫描/data/app/目录下的apk文件 scanDirLI(mAppInstallDir, 0, scanMode, 0); //创建文件夹监控对象,监视/system/preloadapp/目录 mPreInstallObserver = new AppDirObserver(mPreInstallDir.getPath(), OBSERVER_EVENTS, false); mPreInstallObserver.startWatching(); //扫描/system/preloadapp/目录下的apk文件 scanDirLI(mPreInstallDir, 0, scanMode, 0); //创建文件夹监控对象,监视/data/app-private/目录 mDrmAppInstallObserver = new AppDirObserver(mDrmAppPrivateInstallDir.getPath(), OBSERVER_EVENTS, false); mDrmAppInstallObserver.startWatching(); //扫描/data/app-private/目录下的apk文件 scanDirLI(mDrmAppPrivateInstallDir, PackageParser.PARSE_FORWARD_LOCK,scanMode, 0); /** * Remove disable package settings for any updated system * apps that were removed via an OTA. If they're not a * previously-updated app, remove them completely. * Otherwise, just revoke their system-level permissions. */ for (String deletedAppName : possiblyDeletedUpdatedSystemApps) { PackageParser.Package deletedPkg = mPackages.get(deletedAppName); mSettings.removeDisabledSystemPackageLPw(deletedAppName); String msg; if (deletedPkg == null) { msg = "Updated system package " + deletedAppName+ " no longer exists; wiping its data"; mInstaller.remove(deletedAppName, 0); sUserManager.removePackageForAllUsers(deletedAppName); } else { msg = "Updated system app + " + deletedAppName+ " no longer present; removing system privileges for "+ deletedAppName; deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM; PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName); deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM; } reportSettingsProblem(Log.WARN, msg); } } else { mPreInstallObserver = null; mAppInstallObserver = null; mDrmAppInstallObserver = null; }
监控并扫描以下三个数据目录:
/data/app/
/system/preloadapp/
/data/app-private/
最后进入结尾阶段,将扫描到的信息保存到文件中。
[java]
view plaincopyprint?
mFlagInstall = true;
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis());
final boolean regrantPermissions = mSettings.mInternalSdkPlatform != mSdkVersion;
mSettings.mInternalSdkPlatform = mSdkVersion;
updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL | (regrantPermissions
? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL): 0));
ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) {
if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
removed.add(pa);
}
}
for (int i=0; i<removed.size(); i++) {
PreferredActivity pa = removed.get(i);
Slog.w(TAG, "Removing dangling preferred activity: "
+ pa.mPref.mComponent);
mSettings.mPreferredActivities.removeFilter(pa);
}
// can downgrade to reader
mSettings.writeLPr();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,SystemClock.uptimeMillis());
Runtime.getRuntime().gc();
mRequiredVerifierPackage = getRequiredVerifierLPr();
mFlagInstall = true; EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,SystemClock.uptimeMillis()); final boolean regrantPermissions = mSettings.mInternalSdkPlatform != mSdkVersion; mSettings.mInternalSdkPlatform = mSdkVersion; updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL | (regrantPermissions ? (UPDATE_PERMISSIONS_REPLACE_PKG|UPDATE_PERMISSIONS_REPLACE_ALL): 0)); ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>(); for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { if (mActivities.mActivities.get(pa.mPref.mComponent) == null) { removed.add(pa); } } for (int i=0; i<removed.size(); i++) { PreferredActivity pa = removed.get(i); Slog.w(TAG, "Removing dangling preferred activity: " + pa.mPref.mComponent); mSettings.mPreferredActivities.removeFilter(pa); } // can downgrade to reader mSettings.writeLPr(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,SystemClock.uptimeMillis()); Runtime.getRuntime().gc(); mRequiredVerifierPackage = getRequiredVerifierLPr();
至此,PackageManagerService就构造完成了,构造过程认为繁重,Apk文件扫描解析耗费比较长的时间,这是导致开机速度慢的原因。
相关文章推荐
- Android——ArrayAdapter两个构造方法的区别
- java、android 对比两个目录或文件是否是同一个目录或文件的方法
- Android Canvas rotate()和translate()两个方法的研究
- Android中退出多个Activity的两个经典方法
- Android开发实现ScrollView中嵌套两个ListView的方法
- Android中退出多个Activity的两个经典方法
- Android View构造方法第三参数使用方法详解
- Android开发笔记(十一)自定义视图的构造方法
- Android自定义View(一)关于super、this和构造方法
- android自定义控件,其三个父类构造方法有什么区别
- 【Android 界面效果29】研究一下Android滑屏的功能的原理,及scrollTo和scrollBy两个方法
- Android-LayoutInflater中inflate方法两个参数和三个参数的区别
- 在android 两个类之间 get,set方法传参使用
- Android中退出多个Activity的两个方法
- Android逆向之旅---某直播APP的协议加密原理分析以及调用加密方法进行协议参数构造
- Android RadioGroup中设置默认选中RadioButton 后,选中两个的问题 解决方法
- android Kotlin 继承、派生、接口、构造方式,方法、属性重写
- Android中退出多个Activity的两个经典方法
- android81--两个Activity之间跳转时必然会执行的是哪几个方法
- android自定义控件,三个父类构造方法的区别